Page 4 of 14
Re: About Dialogue Actor component
Posted: Thu Mar 11, 2021 12:03 pm
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.
Re: About Dialogue Actor component
Posted: Fri Mar 12, 2021 5:48 am
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
Re: About Dialogue Actor component
Posted: Fri Mar 12, 2021 10:47 am
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.
Re: About Dialogue Actor component
Posted: Fri Mar 12, 2021 11:13 am
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.
Re: About Dialogue Actor component
Posted: Fri Mar 12, 2021 2:16 pm
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.
Re: About Dialogue Actor component
Posted: Fri Mar 12, 2021 6:57 pm
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);
Re: About Dialogue Actor component
Posted: Fri Mar 12, 2021 7:43 pm
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.
Re: About Dialogue Actor component
Posted: Fri Mar 12, 2021 10:57 pm
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.
Re: About Dialogue Actor component
Posted: Fri Mar 12, 2021 11:36 pm
by CHOPJZL
Thanks for the fast reply, I wonder this maybe not your working hours, It's OK to reply when it is convenient
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
Re: About Dialogue Actor component
Posted: Sat Mar 13, 2021 12:11 am
by Tony Li
CHOPJZL wrote: ↑Fri Mar 12, 2021 11:36 pmTo 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)]);
}
}
}