Dialogue State¶
Whether the character is being spoken to, and whether it owes an answer.
This is the lane that gives a character the one state it cannot infer from its own audio, which is Listening.
The Source¶
Implement IDialogueStateSource and assign it to the brain's DialogueStateSource.
| Member | What it returns |
|---|---|
bool IsListeningToSpeaker { get; } |
Whether someone is currently speaking to this character |
bool IsWaitingForPlayerResponse { get; } |
Whether this character has finished and is waiting on the player |
FaceCueCharacter ListeningTo => null; |
Optional. The FaceCue character speaking to it, read only while it is listening |
FaceCueCharacter AwaitingResponseFrom => null; |
Optional. The FaceCue character it waits on, read only while it is waiting |
This is the interface a dialogue system implements once. It already knows who is talking to whom, and answering these two questions from that is usually a few lines. A shipped example, the simple dialogue state source under Examples, shows the whole of it as two switches a conversation flips.
Two Values, Each Its Own Lane¶
The two are overridden, released and owned separately. A cutscene can claim the listening lane without touching the waiting one, and each can be held by a different owner.
brain.SetListeningToSpeaker(this, true);
brain.SetWaitingForPlayerResponse(this, false);
| Member | What it does |
|---|---|
void SetListeningToSpeaker(bool value) |
Claims the anonymous lane |
void SetListeningToSpeaker(object owner, bool value) |
Claims the lane as this owner |
bool ReleaseListeningToSpeakerOverride() |
Gives back the anonymous lane. True when there was one to give back |
bool TryReleaseListeningToSpeakerOverride(object owner) |
Gives the lane back only if this owner still holds it. True when it did |
bool ForceClearListeningToSpeakerOverride() |
Takes the lane back whoever holds it. True when there was an override to clear |
WaitingForPlayerResponse has the same five, named the same way (SetWaitingForPlayerResponse, ReleaseWaitingForPlayerResponseOverride and so on). bool ForceClearDialogueStateOverrides() clears both lanes at once.
Naming the Other Character¶
When the one speaking is another FaceCue character, say which. The character keeps whom it listens to, and your code can read it back.
guard.SetListeningToSpeaker(true, captain);
guard.SetListeningToSpeaker(this, true, captain); // as this owner
| Member | What it does |
|---|---|
void SetListeningToSpeaker(bool listening, FaceCueCharacter speaker) |
Claims the anonymous lane, naming the speaker |
void SetListeningToSpeaker(object owner, bool listening, FaceCueCharacter speaker) |
Claims the lane as this owner, naming the speaker |
void SetWaitingForPlayerResponse(bool waiting, FaceCueCharacter responder) |
Claims the anonymous waiting lane, naming whom it waits on |
void SetWaitingForPlayerResponse(object owner, bool waiting, FaceCueCharacter responder) |
The same, as this owner |
They are the same lanes as the calls above, released the same way. Pass null when the other one is not a FaceCue character, the player included. A character named alongside false is ignored, since a character that is not listening is not listening to anyone.
An override replaces the source's answer whole. While it is set, the source's character is not read either, so an override that names nobody reports nobody.
A destroyed character reads back as nobody, and the character carries on listening, since your game said it is.
The Listener Context offers every listening and waiting call on this page as well, so code that holds the listener needs nothing else.
Asking About It¶
| Member | Tells you |
|---|---|
bool IsListeningToSpeaker { get; } |
The resolved value, override or source |
bool IsListeningToSpeakerOverridePresent { get; } |
Whether an override is masking the source |
bool IsListeningToSpeakerOverrideOwner(object owner) |
Whether this owner holds it |
object ListeningToSpeakerOverrideOwner { get; } |
Who holds it |
InputOverrideOwnerKind ListeningToSpeakerOverrideOwnerKind { get; } |
None, Anonymous or Explicit |
bool IsWaitingForPlayerResponse { get; } |
The resolved value, override or source |
bool IsWaitingForPlayerResponseOverridePresent { get; } |
Whether an override is masking the source |
bool IsWaitingForPlayerResponseOverrideOwner(object owner) |
Whether this owner holds it |
object WaitingForPlayerResponseOverrideOwner { get; } |
Who holds it |
InputOverrideOwnerKind WaitingForPlayerResponseOverrideOwnerKind { get; } |
None, Anonymous or Explicit |
FaceCueCharacter ListeningTo { get; } |
Whom the character listens to, override or source. Null when it is not listening or nobody was named |
FaceCueCharacter AwaitingResponseFrom { get; } |
Whom it waits on. Null when it is not waiting, or waits on the player |
On the Listener Context, two more:
| Member | Tells you |
|---|---|
FaceCueCharacter ListeningTo { get; } |
Whom the character attends to. The one to read when you want to know whom it is listening to |
ListeningInput ListeningDecidedBy { get; } |
What made it listen: DirectCall for your code, DialogueSource for the source, None while it is not listening |
Events¶
event Action<DialogueStateOverrideChange> DialogueStateOverrideChanged fires when either lane's override changes. Its DialogueStateOverrideChange carries:
| Field | Holds |
|---|---|
DialogueStateMember Member |
Which value changed: ListeningToSpeaker or WaitingForPlayerResponse |
InputOverrideTransitionKind Transition |
Which kind of change. See Sources and Overrides |
bool HadPreviousOverride |
Whether an override was present before |
bool PreviousValue |
What it was |
InputOverrideOwnerKind PreviousOwnerKind |
How it was held before: None, Anonymous or Explicit |
object PreviousOwner |
Who held it before. On a Vacated change this is a destroyed object: compare it, never use it |
bool HasCurrentOverride |
Whether an override is present now |
bool CurrentValue |
What it is now |
InputOverrideOwnerKind CurrentOwnerKind |
How it is held now |
object CurrentOwner |
Who holds it now |
FaceCueCharacter PreviousCharacter |
The character it named before, or null. It may be destroyed: compare it, never use it |
FaceCueCharacter CurrentCharacter |
The character it names now, or null |
One event serves both lanes, so check Member first.
Where It Reaches¶
Into the conversant state, which resolves to Talking, Listening or Idle and is read by the eyes and by breath. What each of those states changes is set out in Speaking and Listening.
Listening Is the Reason This Lane Exists
A character can tell it is Talking from its own audio. It cannot tell it is Listening, because nothing is playing. This lane is how it finds out, and until you wire it up a character will never resolve to Listening at all.