About Dialogue Actor component

Announcements, support questions, and discussion for the Dialogue System.
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: About Dialogue Actor component

Post by Tony Li »

No, I think those are the only relevant commands except SetDialoguePanel(), which works on the most recently opened dialogue UI.

Lua uses doubles internally, so C# functions that you register with Lua should return doubles.
CHOPJZL
Posts: 97
Joined: Wed Sep 02, 2020 10:05 pm

Re: About Dialogue Actor component

Post by CHOPJZL »

Today I tried further about changing panel during conversation with "LivelyChatBubbles Example". The main goal is to change Actor's panel without using Dialogue Actor component.

The subtitle panel works when I add a test method in StandardUISubtitleControls. If this idea is right, I suggest add this to 2.2.16 too.

Code: Select all

public void OverriderTest(Actor actor, StandardUISubtitlePanel customPanel = null)
        {
            m_actorIdOverridePanel[actor.id] = customPanel;
        }

But the Menu Panel is not successful. This time I called the exist method in StandardUIResponseMenuControls.

Code: Select all

/// <summary>
        /// For speakers who do not have a GameObject, this method overrides the actor's default panel.
        /// </summary>
        public void OverrideActorMenuPanel(Actor actor, MenuPanelNumber menuPanelNumber, StandardUIMenuPanel customPanel)
        {
            if (actor == null) return;
            m_actorIdPanelCache[actor.id] = GetPanelFromNumber(menuPanelNumber, customPanel);
        }
The Function of "GetPanel(Subtitle lastSubtitle, Response[] responses)" is wield. Take the LivelyChatBubbles scene as an example. Even if I remove every place of "Blue" in the conversation, the "playerTransform " is still Blue Actor, This branch never goes to the "else" part

Code: Select all

if (playerTransform != null)
            {
                // If NPC doesn't specify a menu panel, check for an override by player's transform:
                Debug.Log(playerTransform);
                if (m_actorPanelCache.ContainsKey(playerTransform)) return m_actorPanelCache[playerTransform];
            }
            else
            {
                // If no player transform, check for an override by player actor ID:
                var playerID = (lastSubtitle != null && lastSubtitle.speakerInfo.isPlayer) ? lastSubtitle.speakerInfo.id
                    : (responses != null && responses.Length > 0) ? responses[0].destinationEntry.ActorID : -1;
                if (m_actorIdPanelCache.ContainsKey(playerID)) return m_actorIdPanelCache[playerID];
            }
And it is set to Blue Transform in "(responses != null && responses.Length > 0) ? GetActorTransformFromID(responses[0].destinationEntry.ActorID)" at the begining of the GetPanel method
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: About Dialogue Actor component

Post by Tony Li »

Hi,

Version 2.2.16 has this method:

Code: Select all

public void OverrideActorPanel(Actor actor, SubtitlePanelNumber subtitlePanelNumber)
It's also in a patch: DS_SubtitlePanelPatch_2021-02-28.unitypackage

For the menu issue, as long as no GameObject is associated with the player, it should go by the player's database actor ID. Can you send a reproduction project where this doesn't work to tony (at) pioxelcrushers.com? If so, please include steps to reproduce the issue.
CHOPJZL
Posts: 97
Joined: Wed Sep 02, 2020 10:05 pm

Re: About Dialogue Actor component

Post by CHOPJZL »

I have send the project.
Version 2.2.16 has this method:
But still lack a way to change to a custom panel without using Dialogue Actor component.
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: About Dialogue Actor component

Post by Tony Li »

Thanks for sending the project. I received it. I'll check the project and look into changing to custom panels, and reply back here later today.
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: About Dialogue Actor component

Post by Tony Li »

Hi,

If you set the Dialogue Manager's Other Settings > Debug Level to Info, it will report that it's using the GameObject "Blue" as the actor:

Dialogue System: Starting conversation 'New Conversation 1', actor=Blue (UnityEngine.Transform), conversant=Yellow (UnityEngine.Transform).

This means the actor has a transform assigned. If the actor has a transform, the UI will only check if an override panel has been assigned to the transform. To assign the override, use this method:

OverrideActorMenuPanel(Transform actorTransform, MenuPanelNumber menuPanelNumber, StandardUIMenuPanel customPanel)

In your custom script, change this line:

Code: Select all

ui.OverrideActorMenuPanel(DialogueManager.masterDatabase.GetActor("Player"), MenuPanelNumber.Custom,theMenuPanel);
to this:

Code: Select all

ui.OverrideActorMenuPanel(DialogueManager.currentActor, MenuPanelNumber.Custom, theMenuPanel);
For subtitle panels, here's a patch that lets you specify a custom panel when calling OverrideActorPanel(Actor actor...):

DS_SubtitlePanelPatch_2021-03-12.unitypackage

Use it like this:

Code: Select all

OverrideActorPanel(DialogueManager.masterDatabase.GetActor("Yellow"), SubtitlePanelNumber.Custom, thePanel);
CHOPJZL
Posts: 97
Joined: Wed Sep 02, 2020 10:05 pm

Re: About Dialogue Actor component

Post by CHOPJZL »

This time it works properly, turns out I forgot to set the Conversant Actor to None in Trigger. What's the purpose of the design that let currentActor store the customMenuPanel? In this Case, Blue is not a Player, and I still need to start a Menu selection by Player's entry.


And still currentActor is a transform, a method that change custom menu panel directly by Actor class is needed. For now I try to write it like this:

Code: Select all

if (DialogueManager.currentActor != null)
        {
            ui.OverrideActorMenuPanel(DialogueManager.currentActor , MenuPanelNumber.Custom, theMenuPanel);
        }
        else
        {
            ui.OverrideActorMenuPanel(DialogueManager.masterDatabase.GetActor(responses[0].destinationEntry.ActorID), MenuPanelNumber.Custom, theMenuPanel);
        }
Is the currentActor accurate when using simultaneous conversations?

Can we make the branch behave differently according to different Conversation Participants? For example, If the Actor is Player, open the menu panel; If the Actor is Blue, just choose a random route.
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: About Dialogue Actor component

Post by Tony Li »

CHOPJZL wrote: Fri Mar 12, 2021 7:43 pmWhat's the purpose of the design that let currentActor store the customMenuPanel? In this Case, Blue is not a Player, and I still need to start a Menu selection by Player's entry.
If the menu is a reply to the actor, it may use the menu panel assigned to that actor.
CHOPJZL wrote: Fri Mar 12, 2021 7:43 pmIs the currentActor accurate when using simultaneous conversations?
No, currentActor only refers to the most recently started conversation. To get the actor and conversant of each conversation, use DialogueManager.instance.activeConversations. However, you may find it easier to check the subtitle's speakerInfo and conversantInfo. Example:

Code: Select all

void OnConversationLine(Subtitle subtitle)
{
    Debug.Log($"In this conversation, the current speaker is {subtitle.speakerInfo.Name} and listener is {subtitle.listenerInfo.Name}");
}
CHOPJZL wrote: Fri Mar 12, 2021 7:43 pmCan we make the branch behave differently according to different Conversation Participants? For example, If the Actor is Player, open the menu panel; If the Actor is Blue, just choose a random route.
If the database actor assigned to the nodes is a player (Is Player checkbox is ticked) and there are more than one node -- or if the Dialogue Manager's Always Force Response Menu checkbox is ticked -- then it will always act as a menu. However, since the UI classes are virtual, you can override the behavior to check the actual runtime actors and change the behavior. If you need more instructions, please provide a specific example with details.
CHOPJZL
Posts: 97
Joined: Wed Sep 02, 2020 10:05 pm

Re: About Dialogue Actor component

Post by CHOPJZL »

Thanks for the fast reply, I wonder this maybe not your working hours, It's OK to reply when it is convenient :D
To get the actor and conversant of each conversation, use DialogueManager.instance.activeConversations.
Please tell me more about this approach. Since most of my Menu Panel changes happen in OnConversationResponseMenu(Response[] responses), and I will store the necessary parameter like Panel name in the Entry's field.
If you need more instructions, please provide a specific example with details.
Think about a Conversation between PLAYER and NPCAAA has a menu section(more than one PLAYER node). I set the Actor's transform to a gameobject with a NPCBBB Dialogue Actor component. Then the menu section will become a random select like normal NPC conversation did
User avatar
Tony Li
Posts: 22108
Joined: Thu Jul 18, 2013 1:27 pm

Re: About Dialogue Actor component

Post by Tony Li »

CHOPJZL wrote: Fri Mar 12, 2021 11:36 pm
To get the actor and conversant of each conversation, use DialogueManager.instance.activeConversations.
Please tell me more about this approach. Since most of my Menu Panel changes happen in OnConversationResponseMenu(Response[] responses), and I will store the necessary parameter like Panel name in the Entry's field.
DialogueManager.instance.activeConversations is a list of ActiveConversationRecord objects. You can find the one that matches your conversation ID. Here's an example that lists all of the active conversations:

Code: Select all

foreach (ActiveConversationRecord record in DialogueManager.instance.activeConversations)
{
    int conversationID = record.conversationModel.GetConversationID(record.conversationModel.firstState);
    Debug.Log("Conversation {conversationID} uses actor={record.actor}, conversant={record.conversant}");
}
CHOPJZL wrote: Fri Mar 12, 2021 11:36 pmThink about a Conversation between PLAYER and NPCAAA has a menu section(more than one PLAYER node). I set the Actor's transform to a gameobject with a NPCBBB Dialogue Actor component. Then the menu section will become a random select like normal NPC conversation did
No, in this case NPCBBB will be treated like a player. It will show a menu. This is because the nodes in the database are assigned to an actor whose Is Player checkbox is ticked.

However, you could make a subclass of StandardDialogueUI that overrides the ShowResponses() method. Check if the character is a real player or NPCBBB. If it's a real player, call the original ShowResponses(). If it's an NPC, randomly choose a response and send it to the Onclick() method. Example:

Code: Select all

public class MyDialogueUI : StandardDialogueUI
{
    public override void ShowResponses(Subtitle subtitle, Response[] responses, float timeout)
    {
        // (Replace the line below with whatever code you want to use to decide if it's the player or NPCBBB:)
        var actor = DialogueManager.masterDatabase.GetActor(DialogueActor.GetDialogueActorComponent(DialogueManager.currentActor));
        if (actor.IsPlayer)
        {
            base.ShowResponses(subtitle, responses, timeout);
        }
        else
        {
            OnClick(responses[Random.Range(0, responses.Length)]);
        }
    }
}
Post Reply