Efficient dialog/cutscene scripting (advice is welcome)
My game has many (hundreds) of dialogs, mostly between the player character and one NPC (though not always). My current way of handling these is to program them into the script that initializes the scene. So, for instance, I'll set up the character so that when he's clicked on he has several options, one of which invokes a dialog
if (haventTalkedAboutTown)
John.AddDialogueTopic("Town", "TownIcon", TOWN_DIALOG));
where TOWN_DIALOG
is an actual function in my script that gets invoked (via a unityevent)
void TOWN_DIALOG()
{
StartCoroutine(TOWN_DIALOGCo());
haventTalkedAboutTown = false;
UpdateJohn();
}
IEnumerator TOWN_DIALOGCo()
{
Ego.DisablePointer();
Character John = SceneCharacters[0];
Ego.PlayEgoSound("Speech/LBY/A1E5CU36PF1");
while (Ego.isTalking) { yield return new WaitForSeconds(0.1f); }
John.StartDialogue("Speech/LBY/A1E5CU36PF2");
while (John.isTalking) { yield return new WaitForSeconds(0.1f); }
if (John.DialogueTopicsLeft) John.UpdateConversation();
else Ego.EnablePointer();
}
While this solution works, the result is a lot of duplicate code, and if I ever decide to update the implementation, it's kind of a nightmare. The above example is 11 lines, two functions, for two lines of dialog (the coroutine apparently can't be invoked by the unityevent.AddListener, which is why there are two functions).
One thing I've contemplated is making a small text file in the resources, and loading it through that. So, for instance, the above interaction could be
StartConversation(John, Ego)
SetFalse(haventTalkedAboutTown)
SayDialog(John, Ego, Speech/LBY/A1E5CU36PF1)
Wait
SayDialog(Ego, John Speech/LBY/A1E5CU36PF2)
Wait
UpdateConversation
Then I could have one function that handles the conversation, and parses the file. However, this requires writing a parser that is able to evaluate truth values in the game variables, and be able to understand a lot of different commands. Does anybody have any suggestions about how best to implement a dialog system like this? Am I on the right track?
Answer by ericbegue · Dec 14, 2016 at 07:42 PM
If your are looking for a scripting solution, you might be interested by Panda BT (www.pandabehaviour.com). It's a framework based on Behaviour Tree, which is originally an AI technique, but it can come as handy for your dialog/cutscene scripting. Since the behaviour trees are writing into small text files that you can use to do your scripting.
The building blocks of a behaviour tree are 'tasks'. A task is some process that runs for a period of time (several frames) before it completes in success or failure. A task is simply implemented as a function in C#. For instance, you could implement the task 'DoDialog' this way:
public class DialogBT : MonoBehaviour
{
[Task] // <-- This marks a method as a task so we can use it from a BT script.
void DoDialogue( string name, string dialog )
{
var task = Task.current;
if (task.isStarting)
{// Use this for task initialization.
// Look for the entity with the given name.
var entities = FindObjectsOfType<DialogEntity>();
foreach(var e in entities)
{
if(e.name == name)
{// found it...
// Attach the entity to the task so we can use it later (below).
// (item is used to store any data required to process a task)
task.item = e;
break;
}
}
}
var entity = task.item as DialogEntity;
// Start the dialogue on the first frame.
if (task.isStarting)
entity.StartDialogue(dialog);
// When the entity is not talking anymore, succeed the task. We're done.
if ( !entity.isTalking )
task.Succeed();
}
}
Once, you've defined some tasks you can use them from a BT script, so your example would become something like:
sequence
DisablePointer("Ego")
PlaySound("Speech/LBY/A1E5CU36PF1")
DoDialog("John", "Speech/LBY/A1E5CU36PF2")
EnablePointer("Ego")
Also, you can visualize the script as it is running in the Inspector. That's valuable for debugging or just to inspect what's going on.
There's a lot you can do with behaviour tree, I've just scratch the surface here. If you have question about using this tool, you're welcome on this thread.
Your answer
![](https://koobas.hobune.stream/wayback/20220612102706im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Camera-movement within another camera 1 Answer
How can i make an Dialogue for an NPC 0 Answers
How to continue dialog automatically (without pressing buttons)? 1 Answer
NPC Dialog 1 Answer
Errors on Script? 1 Answer