NPC Conversations

Announcements, support questions, and discussion for the Dialogue System.
bbjones
Posts: 21
Joined: Mon Aug 17, 2020 11:56 am

NPC Conversations

Post by bbjones »

Looking for guidance or examples on how to do this.

Two scenarios:

1) Random bark conversations between 2 or more NPCs.
A group of NPCs is wandering around together, NPC-1 of them barks out "it's cold outside", NPC-2 responds "yeah", NPC-3 responds "whimp", NPC-2 responds "shut up!"

I'm saying barks because they would look like other random singular barks.

I'm not clear on how that would both be stored in the dialogue database and how to get the conversation to flow correctly.
It doesn't really matter who replied first or last, but it would make sense that they reply one at a time.
This scenario isn't entirely random barks either, they are bark responses based on a specific topic (cold outside), and the "whimp/shutup" part is more about those two particular NPCs having an established relationship where they mock each other etc.

Another scenario of that could be in a night club scene where there are potentially several conversations going on between different groups at the same time.

If these conversation sets need to be fully scripted I can do that to, but then how to get the conversation spread out between 3 or more NPCs?

2) Bascially the same idea but between two NPCs only and based on a controlled activity.
NPC-1 is the doctor, NPC-2 is the patient.
The patient is in a known state "needs_medical" and the doctor is doing an established job "patient_checkups".
When the doctor gets close enough to NPC-2 their conversation would start, all based on a variety of responses at each level, and likely some dynamic stuff based on variables like if the patient has an injury on their arm or leg. For example:
Doc: "how are you today"
Patient: "my [bodypart] hurts when I do this."
Doc: "Then don't do that, wocka wocka wocka"

An alternative in the exact same scenario might be:
Doc: "what did you do this time?"
Patient: "hurt my [bodypart] chasing chickens"
Doc: "well I've got just the thing for you"

I think I can see how to get all that done with barks, triggers, several different specific conversations in the database etc, but if there is any guidance on the most effective direction to take that may save me time.

There is one example on the extras page (simultaneous conversations) but the package is very broken in unity v2020.1. I can't even open that database to examine their conversation structure.
https://www.pixelcrushers.com/dialogue-system-extras/

Cheers
User avatar
Tony Li
Posts: 22051
Joined: Thu Jul 18, 2013 1:27 pm

Re: NPC Conversations

Post by Tony Li »

Hi,
bbjones wrote: Mon Aug 24, 2020 6:56 pm1) Random bark conversations between 2 or more NPCs.
A group of NPCs is wandering around together, NPC-1 of them barks out "it's cold outside", NPC-2 responds "yeah", NPC-3 responds "whimp", NPC-2 responds "shut up!"
I recommend a conversation, not a bark, using overhead subtitle panels. See How To: Overhead Conversation Bubble Text.

You can vary the GameObjects who speak NPC-1's and NPC-2's lines by assigning different GameObjects to the Dialogue System Trigger or DialogueManager.StartConversation("title", actor, conversant). But the Dialogue System will look for GameObjects that match the actors NPC-3+ in the dialogue database.
bbjones wrote: Mon Aug 24, 2020 6:56 pm2) Bascially the same idea but between two NPCs only and based on a controlled activity.
Add a Dialogue System Trigger set to OnTriggerEnter to NPC-2 (patient). Configure Conditions > Accepted Tags to require the doctor's tag, or assign the doctor's GameObject to Accepted GameObjects. You can set a custom actor field on NPC-2 to record when "needs_medical" is true, or you can register a C# method with Lua. Then check it in Conditions > Lua Conditions. Then configure Actions > Start Conversation to start the conversation.

In the conversation, branch on actor fields or C# methods registered as Lua functions. If you're writing the conversation to be applicable to any number of patients, keep in mind that the Lua variable Variable["ConversantIndex"] will be set to NPC-2's actor name. So if you want to check a custom field named Pulse on NPC-2, use:

Code: Select all

Actor[Variable["ConversantIndex"]].Pulse
bbjones wrote: Mon Aug 24, 2020 6:56 pmThere is one example on the extras page (simultaneous conversations) but the package is very broken in unity v2020.1. I can't even open that database to examine their conversation structure.
Older packages were made in version 1.x of the Dialogue System. To use them, you'll have to run the updater (Tools > Pixel Crushers > Dialogue System > Tools > Run 1x to 2x Updater).
bbjones
Posts: 21
Joined: Mon Aug 17, 2020 11:56 am

Re: NPC Conversations

Post by bbjones »

Tony Li wrote: Mon Aug 24, 2020 9:00 pm
You can vary the GameObjects who speak NPC-1's and NPC-2's lines by assigning different GameObjects to the Dialogue System Trigger or DialogueManager.StartConversation("title", actor, conversant). But the Dialogue System will look for GameObjects that match the actors NPC-3+ in the dialogue database.
Right, it seems easy enough to dynamically change who the main actor and conversant are since there are fields for those.

But what's a strategy for assigning random NPCs for actors 3+?

Would I make the conversation in the database with generic actors NPC 1,2,3,4 etc and then change the NPC's assigned actor field on the Dialogue Actor component to match one of the random NPC actors in the database when a new conversation starts?

While I don't think I'm going to bother showing actor names or portraits in the bubble UI, I do want to log conversations on who said what, and every NPC has their own unique name. Would I dynamically change the database actor DisplayName to match the in-game NPC's correct actor name?

After the conversation I would then set the NPCs back to their original actor names, or just track that separately somewhere.
User avatar
Tony Li
Posts: 22051
Joined: Thu Jul 18, 2013 1:27 pm

Re: NPC Conversations

Post by Tony Li »

Let's say you have 3 actors named Ann, Bob, and Carl. They each have a GameObject with the same name, and a Dialogue Actor component set to their actor names.

In your dialogue database, you've defined 3 more actors named NPC-1, NPC-2, and NPC-3, and a conversation titled "Cold":
  • NPC-1:"it's cold outside"
  • NPC-2: "yeah"
  • NPC-3: "whimp"
  • NPC-2: "shut up!"
During play, you decide that you want Ann to be NPC-1, Bob to be NPC-2, and Carl to be NPC-3.

Assigning Ann and Bob are easy:

Code: Select all

DialogueManager.StartConversation("Cold", Ann, Bob);
Carl requires an additional step. You need to tell the CharacterInfo registry that Carl is associated with NPC-3:

Code: Select all

CharacterInfo.RegisterActorTransform("NPC-3", Carl.transform);
DialogueManager.StartConversation("Cold", Ann, Bob);
If Carl's lines show up as spoken by "NPC-3", use this line of code, too:

Code: Select all

DialogueLua.SetActorField("NPC-3", "Display Name", "Carl");
bbjones
Posts: 21
Joined: Mon Aug 17, 2020 11:56 am

Re: NPC Conversations

Post by bbjones »

That all makes sense, but I can't seem to get it working.

The only way I can get conversation to show up on the right people is to have them match the assigned actor/conversant from the editor.

I've tried using triggers, Opsive behaviour designer nodes (which is just DialogueManager.StartConversation()), trying various different actor/conversant assignments etc.

It seems like the DialogueManager.StartConversation() is ignoring my override actor/conversant, same when using the dialogue trigger, it is instead only using whatever was assigned in the editor.

For example, if I have 2 objects in scene, NPC1 and 2, have actors assigned to them, and have a trigger on NPC1 that starts conversation "Test1" which is just some back and forth one-liners between 2 actors.

The trigger links the scene objects for NPC1/2 to the actor/conversant fields on the StartConversation action of the tirgger.
The conversation still plays with the original actor names only. It doesn't show the NPC1/2 names and doesn't use their scene objects dialogue UI.

I can get NPC1/2 dialogue working correctly, but only if my database conversation has them assigned in the editor on each node.

I'll keep looking through the docs and examples but I must be missing something obvious.
User avatar
Tony Li
Posts: 22051
Joined: Thu Jul 18, 2013 1:27 pm

Re: NPC Conversations

Post by Tony Li »

I'll put together a short example later today.
User avatar
Tony Li
Posts: 22051
Joined: Thu Jul 18, 2013 1:27 pm

Re: NPC Conversations

Post by Tony Li »

Here's an example scene. It's set up as described above.

DS_MultipleNPCExample_2020-08-25.unitypackage
bbjones
Posts: 21
Joined: Mon Aug 17, 2020 11:56 am

Re: NPC Conversations

Post by bbjones »

Works as expected.

Thanks a bunch for taking the time to make the example.

I changed it a bit adding a dialogue trigger to start it, modified the code to only register the 3rd npc, and added bubble subtitle UIs to some new game objects for each character.

All works as it should. It is pretty straight forward so not sure why my other tests were having problems but I can use this example as a starting point.

I made a short video into a GIF to show the result.
3npcBubbleConversation.gif
3npcBubbleConversation.gif (69.45 KiB) Viewed 1494 times
User avatar
Tony Li
Posts: 22051
Joined: Thu Jul 18, 2013 1:27 pm

Re: NPC Conversations

Post by Tony Li »

Thanks for the GIF! Nice to see the example it in action.
bbjones
Posts: 21
Joined: Mon Aug 17, 2020 11:56 am

Re: NPC Conversations

Post by bbjones »

Not sure how to explain this but this morning nothing is working properly in my main dialogue database, or any new database I create and test with in my main project.

I've reduced it to trying a very simple dialogue with 2 npcs.

I use the example database you sent earlier with 3 npcs, and this works where it maps my in-game objects to the actor/conversant using a trigger to start the conversation.

In the same scene I switch back to my main database (which was working fine yesterday) and I get a variety of incorrect dialogue depending how I set it up.

Either no dialogue at all, or the dialogue works but doesn't recognize my mapped actor/conversant, instead it uses the NPC names the from the editor and uses the default UI.

I have tried making a new dialogue database, no difference.

I have made an entirely new scene with a new database.
Added 4 actors: bob, fred, npc1, npc2
Make a new conversation between npc1/2.
Add 2 game objects to scene.
Give one object actor=bob
The other actor=fred and a trigger to start the new conversation
Link the 2 game objects to the trigger actor/conversant fields and play.

The conversation plays but shows the npc1/2 names, not the mapped actor names.

Back in the example scene you sent.
I link the dialogue manager to my new test database and remap the actors to my new test conversation.

Same incorrect results where they are not showing mapped actor names, and are not using the mapped actor UI, but are instead showing the default NPC names and using the default UI.

I have tried deleting the PixelCrushers Plugins folder and re-importing. No difference.
I have made an entirely new empty project, imported only Dialogue System, repeated the test steps above in a new scene (for bob/fred) and it works properly.
I can export that test scene (from the new clean empty project that works) and import it to my main project and that works.
If I remap that working scene to use a database that was created in my main project it does not work.
So these issues seem limited to my main project only, and only with databases I create.

Attached are 2 images:
These show the conversation from my main project and the new empty test.
You can see there are differences despite me setting them up the exact same way.
My main project shows actor labels on nodes, and the Actor/Conversant in the bottom right corner is different.

Main Project - broken:
apoc4scene.png
apoc4scene.png (51.38 KiB) Viewed 1478 times
Clean project - works:
cleanProjectScene.png
cleanProjectScene.png (48.97 KiB) Viewed 1478 times
Any ideas? I've spent several hours fighting this and it just isn't making any sense. It's like every database I create in my main project is corrupt or broken in some way.

The other differences are in my main project I've imported extras, examples, and integrations.
Post Reply