Emotion Balloons and Emotes
An emotion balloon is the small animated bubble that pops over a character's head: the exclamation mark when a trainer spots you, a heart over your follower, a question mark over a confused NPC. MCE ships 14 balloons of its own, original drawings that every game has, and lets a game bring its own set on top of them.
The same balloons serve four different callers:
| Caller | How it asks for a balloon |
|---|---|
| The player | Function-key hotkeys (F1 to F12, Shift+F1, Shift+F2) |
| A script | The PlayEmotion node in a CommandGraph |
| The follower | A heart while it growls at you (MonsterFollowerController) |
| Other players | In the MMORPG layer, a balloon shown over a remote avatar: see Online Emotes |
All of them ask by name.
The 14 Engine Balloons
The names live in EmotionBalloonNames (namespace OpenMon.MCE.Characters.Followers.Talk). EmotionBalloonNames.All lists them in the order the hotkeys use:
| Name | Hotkey |
|---|---|
exclamation_mark | F1 |
question_mark | F2 |
heart | F3 |
music_note | F4 |
anger | F5 |
sweat_drop | F6 |
sleep | F7 |
happy | F8 |
sad | F9 |
shocked | F10 |
idea | F11 |
ellipsis | F12 |
sparkle | Shift+F1 |
determined | Shift+F2 |
The engine's own set is a ScriptableObject at Resources/Characters/EmotionBalloons/DefaultEmotionBalloons, so any game finds it without wiring anything.
Player Hotkeys
PlayerCharacter adds a PlayerEmoteInput component to itself as soon as it starts receiving input. From then on the hotkeys above show the matching balloon over the player.
A hotkey only fires when the player is free to act:
- the player is not interacting (no dialog, menu or cutscene holds it),
- the game is running (time scale above zero),
- the previous balloon has finished -- there is one balloon at a time.
Whenever the local player shows a balloon, PlayerEmotes.Played is raised with the balloon's name. That event is how the online layer learns that it has to tell the other players; you can listen to it too:
using OpenMon.MCE.Characters;
PlayerEmotes.Played += name => Debug.Log($"The player showed '{name}'.");
PlayerEmotes.NameForHotkey(functionKey, shift) maps a key to its balloon name (it returns null for a key that carries none).
Showing a Balloon From a Script
Add a PlayEmotion node (Create Command / Animations / PlayEmotion) to any graph:
| Field | Meaning |
|---|---|
| Emotion | The balloon's name (default heart). A name that nobody has plays nothing, not even a sound. |
| Target | The character that shows it. Empty: the actor that runs the graph. |
| On Player | Show it over the player instead. |
| Wait | Hold the graph until the balloon is gone (on by default). Off, the graph goes on while the balloon plays. |
PlayExclamation is the older, single-purpose sibling: it shows the exclamation over a character or over the player, using the game's own exclamation when its set has one.
The Follower's Heart
A follower that has no talk table of its own (a game that did not import one) shows the engine's heart over itself while it growls when you talk to it. Code can ask the follower for any balloon:
// follower is the MonsterFollowerController of the player's follower
StartCoroutine(follower.ShowEmotion(EmotionBalloonNames.Sparkle));
Bringing Your Own Balloons
A game replaces or extends the engine's balloons with an Emotion Balloon Set (Create > MCE > Characters > Emotion Balloon Set):
| Field | Meaning |
|---|---|
balloons | The balloons: each has a name, its sprites, the sprite shown on every update (spriteByUpdate) and the height of the jump on every update (heightByUpdate). Timelines run at 60 updates per second; 16 map units make one tile. |
aliases | Another name for a balloon -- a script's name for one the cartridge calls differently. |
sound | The sound a balloon makes when it pops up. Empty: silent. |
Assign the set to the Emotion Balloons field of your MCESettings asset. When anything asks for a balloon, EmotionBalloonSet.Resolve(gameSet, name) looks in this order:
- the game's own set, by name or alias;
- the engine's own set (
EmotionBalloonSet.Default).
So a game that defines heart gets its heart everywhere -- hotkey, script, follower, and balloons that other players see -- and a game that defines nothing still has all 14.
Games imported from a cartridge (see Imported Games and Game Profiles) get their own set built by the importer, and the game profile assigns it to MCESettings (and gives it back when the profile is restored).
Over Any Body
A popup (CharacterPopUpController) draws the balloon over the player and over every actor. For anything that has no popup -- a follower, another player's avatar, your own prop -- use EmotionBubbleOverBody:
StartCoroutine(EmotionBubbleOverBody.Play(someTransform, balloon, clock: null));
It hangs a temporary object from the body, sits it over the highest of the body's sprites, centers it on all of them and follows the balloon's jump on every update. When the balloon ends the object goes. A balloon with nothing to draw, or a body without sprites, does nothing.
Reference
| Type | Namespace | Role |
|---|---|---|
EmotionBalloonNames | OpenMon.MCE.Characters.Followers.Talk | The 14 names and All |
EmotionBalloonSet | OpenMon.MCE.Characters.Followers.Talk | A set of balloons, Default, Resolve, Find |
EmotionBubbleOverBody | OpenMon.MCE.Characters.Followers.Talk | Draw a balloon over any body |
PlayerEmotes | OpenMon.MCE.Characters | Hotkey mapping and the Played event |
PlayerEmoteInput | OpenMon.MCE.Characters | Reads the hotkeys |
CharacterPopUpController | OpenMon.MCE.Actors | PlayEmotion(name), PlayBalloon(balloon, sound) |
PlayEmotion | OpenMon.MCE.Actors.CommandGraph.Animations | The script node |