Page 2 of 2

Re: NPC Conversations

Posted: Thu Aug 27, 2020 11:53 am
by bbjones
Adding link from my OneDrive to a package with an example scene (fred/bob) from my main project that does not work correctly.
https://1drv.ms/u/s!AjLMZMLArtRQ_Elv5j1 ... w?e=dgxb7z

Re: NPC Conversations

Posted: Thu Aug 27, 2020 12:25 pm
by Tony Li
Hi,

Thanks for sharing the example scene. When you assign GameObjects to the Dialogue System Trigger's Conversation Actor and Conversation Conversant fields, they will be associated with the conversation's Actor and Conversant as defined in the conversation's properties. To inspect the conversation's properties, open the conversation in the Dialogue Editor and click on blank canvas space.

In TEST03_Dialogue Database, the conversation's Actor and Conversant are Player and bob.

Your Dialogue System Trigger's Conversation Actor and Conversation Conversant fields map the conversation's Actor (Player) to the _Bob GameObject and the Conversant (bob) to the _Fred GameObject.

However, the dialogue entry nodes themselves use the actors npc1 and npc2 as the speakers. These aren't associated with any GameObjects, so they just show their database actor names.

The solution is to inspect the conversation's properties. Change the Actor dropdown to npc1 and the Conversant dropdown to npc2.

Re: NPC Conversations

Posted: Thu Aug 27, 2020 12:54 pm
by bbjones
Ok that makes sense, so I need to register actors in code instead of trying to use the default mapping.

What I had started doing was using placeholder actors in the node editor so I could color nodes to make it easier to follow visually. Because I expect to override the actor depending on which NPC in-game is talking.

For example I have these actors:
Group - black
To_NPC - dark green (actor)
RandomNPC - light green (conversant)
To_Player - dark blue (actor)
Player - light blue (conversant)
Red - links to another conversation

So if I only get 2 actors mapped for free, I may map:
Actor->To_NPC
Conversant->RandomNPC
That would at least cover all my generic NPC dialogue, and I would craft my trees to make sure that is the "default" dialogue.

But, as soon as I'm doing a conversation with the player (or unique named NPCs) I have to register both the "To_Player" and "Player" actors, and all the others?

Or perhaps to just be safe I'll always map everyone, that way I know I've got everyone mapping to the right nodes.

Any suggestions on how to do it more effectively?
I'm using Opsive behaviour designer but I think I'll have to write my own custom integration task so I can deal with all the actor mapping.

Here's a screenshot showing how I'm trying to use generic actor names and colors to organize my conversation. This is still a very simple conversation. I've yet to add my conditions and alternate branches etc.
coloredNodes.png
coloredNodes.png (74.82 KiB) Viewed 689 times

Re: NPC Conversations

Posted: Thu Aug 27, 2020 1:17 pm
by Tony Li
Given your requirements, it might be the most straightforward to map them all in code right before starting the conversation. If you map all actors in code, pass null for the actor and conversant transforms when starting the conversation.

Re: NPC Conversations

Posted: Thu Aug 27, 2020 2:05 pm
by bbjones
Then how might I go about getting the various Actor variables if I'm mapping everything?
Do I create new variables for all the placeholder actors?
Do I have to manually map all the actor fields and custom template fields?

I see SetParticipants() in the API, and while that might work for actor/converstant I will have more than just those 2 actors to work with, and need to access their other fields and custom fields.

Previously you suggested this to register a 3rd dialogue actor.

Code: Select all

CharacterInfo.RegisterActorTransform("NPC-3", Carl.transform);
DialogueManager.StartConversation("Cold", Ann, Bob);
And suggested if needed to change an actor property:

Code: Select all

DialogueLua.SetActorField("NPC-3", "Display Name", "Carl");
Also In conversation text, how would I get the right actor index if I can't use this?
"Hello [lua( Actor[Variable[“ConversantIndex”]].InformalName )], how are you?”

I was having trouble with this already, but how would I also get the actor variable for conditions?
In one condition I'm trying to determine if the actor is the player so I can branch into a different sub-conversation, but I can't get the syntax right. This doesn't work:

Code: Select all

Actor[Variable[“ConversantIndex”]].IsPlayer == true

Re: NPC Conversations

Posted: Thu Aug 27, 2020 3:00 pm
by Tony Li
Let's say your conversation properties specify that the conversation actor is NPC-1 and the conversation conversant is NPC-2. The conversation also involves NPC-3.

You can associate all three GameObjects in code:

Code: Select all

CharacterInfo.RegisterActorTransform("NPC-1", ann.transform);
CharacterInfo.RegisterActorTransform("NPC-2", bob.transform);
CharacterInfo.RegisterActorTransform("NPC-3", carl.transform);
Then start the conversation without specifying actor and conversant GameObjects:

Code: Select all

DialogueManager.StartConversation("Medical Checkup"); // Equivalent to passing null for actor & conversant transforms)
When the conversation starts, the Dialogue System will try to associate GameObjects with the conversation's actor and conversant. Since DialogueManager.StartConversation() did not specify GameObjects, it will associate the conversation actor (NPC-1) with the GameObject registered to NPC-1, which is Ann. It will set Variable["Actor"] to "Ann" (display name) and Variable["ActorIndex"] to "Ann" (actor Name).

Likewise for Bob and the conversant.

When it gets to NPC-3, it will associate it with Carl. But there are no Variable["Actor"] / Variable["ActorIndex"] equivalents for additional participants beyond the main actor and conversant. However, you can set a variable on your own:

Code: Select all

CharacterInfo.RegisterActorTransform("NPC-1", ann.transform);
CharacterInfo.RegisterActorTransform("NPC-2", bob.transform);
CharacterInfo.RegisterActorTransform("NPC-3", carl.transform);
DialogueLua.SetVariable("NPC3Index", "Carl");
DialogueManager.StartConversation("Medical Checkup"); // Equivalent to passing null for actor & conversant transforms)
Then your Conditions and Scripts can work with Actor[Variable["NPC3Index"]].InformalName.