- Home /
Will this dialogue tree approach cause performance issues?
Hello, I am trying to create multiple NPCs, each with their own dialogue trees. I am wondering if my approach is particularly inefficient.
In my approach, there is one NPC class with an NPC sorter method and individual methods per unique NPC type. There are bools to identify which type of NPC this GameObject represents and the NPC sorter method must move through a list of if statements to check each bool and identify the NPC type. Once the NPC type is identified, the appropriate NPC method is called and moves through a case switch to print the dialogue.
public class NPC : MonoBehaviour
{
string lineToPrint;
public bool man1; //This identifies the NPC type
public bool man2; //more bools as more NPCs are added, etc...
public void treeHandler(string line) //This method identifies the type of NPC
{ //the script should be representing on
if (man1) //this instance of the GameObject
{
talkingMan1(line);
}
if (man2)
{
talkingMan2(line);
}
}
public void talkingMan1(string line)
{
switch (line)
{
case "1": //More cases will be added as the dialogue
print("Hello..."); break;//gets more complicated
default:
print("I don't know what to say"); break;
}
}
public void talkingMan2(string line)
{
switch (line)
{
case "1":
print("...world!"); break;
default:
print("I don't know what to say"); break;
}
}
Do you think falling through the potentially large number of if statements and switch cases will cause performance issues? Is there a more elegant solution? There will only be more bools to check and switch cases to go through as I continue. I am scripting for use on phones.
Well, the best way would be to have a script for each guy. Since you are about to write their lines, whether it is on this script or on separate is the same amount of work. For the compiler, it is less cycles checking who is the game object.
generally making a single script for all NPCs is more efficient only if this script will have a lot of shared data. and even in that case possible to make a shared class and unique script for each NPC. for example:
public abstract class NPC : $$anonymous$$onoBehaviour { public int bla // some public data shared for all NPCs public void blabla() // some public methods shared for all NPCs public abstract void blablabla() // some public methods that $$anonymous$$UST be at each NPC but it is unique for each NPC }
public class Trader$$anonymous$$an : NPC { public void blablabla() // unique methods implemented here, all shared methods and properties are already in this instance }
the main bonus you got from this method - you can get a Trader$$anonymous$$an (Store$$anonymous$$eeper, $$anonymous$$agicBla...) just as type of NPC and you even needn't to check who exactly this man is. and if you need execute an unique method on it you just execute 'blablabla();' - this executes blablabla that implemented unique for each NPCs, but you execute NPC.blablabla() regardless of man type
Scroodge$$anonymous$$, I'm not sure how this would look like in Unity. Would the abstract class be in its own script, and then I'd make a new script for each NPC type that inherits from the abstract class?
Wouldn't I still need to know who the man is, then? Since to get the component and call its unique methods, I'd still have to call
GameObject.GetComponent(SomeUniqueNPCScript).blablabla
even if SomeUniqueNPCScript inherited from the abstract class NPC. Sorry for making you spell this out for me.
in unity this will looks like one script for base class and one for each unique man. just like in code example above.
method 'blablabla' can be called independent of man type. so you can GameObject.GetComponent<NPC>().blablabla()
you just should write abstract method in base class for this call method will possible. that in child you'll should write a real method (or else it will not compile)
so for example you can use it for methods like 'UserAttacks', 'EnemyIsClose', 'UserWantsToTalk' and so on - all method can unique writed in each man class.
also be sure you can use overrides as well. i mean you can write method
virtual void UserAttacks() { run away; }in base class - it means that NPC runs away from user if he attacks NPC. and make an override
override void UserAttacks() { attack back; }for one or some mans to make it's reaction other then in base class
You mean to say if I make a GameObject and attach the script named Trader$$anonymous$$anScript (which inherits from the NPC abstract class), I can use GameObject.GetComponent();
and it will point to the Trader$$anonymous$$anScript ins$$anonymous$$d of the NPC script??
That's weird.
Answer by ScroodgeM · Jul 21, 2012 at 05:57 PM
more elegant (IMHO) can be solution like this:
create a manID as enum list to select man from list, not by ID
generate eventID (type int) based on manID (int from enum) and textLineID, for example manIDx10000+textLineID. so man1 has eventIDs 10001, 10002, 10003, man2 has 20001, 20002
create a Dictionary with eventIDs and stringLines of phrases
create a single method that handles by eventID all other events.
example of single method:
//just print an unique message for this man for this line id print (phrasesDictionary.GetValue(eventID)); //additional actions below if needed if (new List(){10001, 20001, 20002}.Contains(eventID)) { move forward } if (new List(){10002}.Contains(eventID)) { attack } else { make a smile }
This sounds really interesting, it'll take me some time to understand what you mean haha.
I will start reading about enums, Dictionary, and eventIDs!
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Dll call 10x slower in Unity 3 Answers
First time a method is executed is ~4 times slower 0 Answers
Understanding Raycast How Actually works in Unity [As Algorithm] 2 Answers
Low Priority Methods In LateUpdate? 1 Answer