Unity3d Unity如何创建对话树?

Unity3d Unity如何创建对话树?,unity3d,dialog,composite,Unity3d,Dialog,Composite,所以我为一个简单的对话树设置了这个程序,我想在unity编辑器中显示一个问题和两个选项,如果你点击一个选项,你可以转到树的另一个层次或者一个叶子。我想使用复合设计模式创建单独的级别实例,每个实例都有一个问题和两个选项的不同参数,并将它们添加到一个列表中。我一直坚持的是如何从第一层开始,并根据我按下的按钮沿树向下移动。看起来无论我做什么,它都只显示添加到列表中的最后一级参数。我能想到的最好的方法是在按钮点击事件中添加一些移位列表功能。如果有人能提出一些想法,我将不胜感激。多谢各位 public c

所以我为一个简单的对话树设置了这个程序,我想在unity编辑器中显示一个问题和两个选项,如果你点击一个选项,你可以转到树的另一个层次或者一个叶子。我想使用复合设计模式创建单独的级别实例,每个实例都有一个问题和两个选项的不同参数,并将它们添加到一个列表中。我一直坚持的是如何从第一层开始,并根据我按下的按钮沿树向下移动。看起来无论我做什么,它都只显示添加到列表中的最后一级参数。我能想到的最好的方法是在按钮点击事件中添加一些移位列表功能。如果有人能提出一些想法,我将不胜感激。多谢各位

public class Level : MonoBehaviour {

  bool button1Pressed;
  bool button2Pressed;

 private void Start()
 {


     Level Level1 = new Level("Hello", "Hi", "Shut Up");
     Level leaf1 = new Level("Don't be Rude");

     Level Level2 = new Level("What you Doing?", "Not Much", "None of your Business");
     Level leaf2 = new Level("Well Excuuuuse Me");

     Level Level3 = new Level("Can I do that too?", "Sure", "Go Away");
     Level leaf3 = new Level("Fine. Be a Jerk");

     Level Level4 = new Level("This is boring, can we do something else?", "Why not?", "You're boring");
     Level leaf4 = new Level("I'll go be boring somewhere else");

     Level Level5 = new Level("You want ice cream?", "Sounds Good", "I'm allergic");
     Level leaf5 = new Level("ok.......");
     Level leaf = new Level("I Want Chocolate");      

     Level1.add(Level1);
     Level1.add(leaf1);

     Level2.add(Level3);
     Level2.add(leaf2);

     Level3.add(Level4);
     Level3.add(leaf3);

     Level4.add(Level5);
     Level4.add(leaf4);

     Level5.add(leaf5);
     Level5.add(leaf);

 }

 public static Text Textbox;
 public static Button Button1;
 public static Button Button2;

     public string OptionA;
     public string OptionB;
     public string Question;

     public string Leaf;

     private List<Level> levels;

     public Level(string question, string optionA, string optionB)
     {
         this.Question = question;
         this.OptionA = optionA;
         this.OptionB = optionB;

     GameObject.FindGameObjectWithTag("Level").GetComponentInChildren<Text>().text = Question;
     GameObject.FindGameObjectWithTag("OptionA").GetComponentInChildren<Text>().text = OptionA;
     GameObject.FindGameObjectWithTag("OptionB").GetComponentInChildren<Text>().text = OptionB;

     levels = new List<Level>();

     }

     public Level(string leaf)
     {
         this.Leaf = leaf;
         Textbox.text = leaf;
     }

     public void add(Level lvl)
     {
         levels.Add(lvl);
     }

     public List<Level> getLevels()
     {
         return levels;
     }

 public void Button1Pressed()
 {

 }
 public void Button2Pressed()
 {

 }

简短回答:所有节点都知道它们的父节点和子节点


有几种方法可以解决这个问题。我将解释一种使用具有多个节点类的树结构的方法。首先,我们可以检查与玩家的交互,如您所述:

  • 选择对话(说)
  • 观察对话响应(倾听)
我们还需要考虑一些重要的条件:

  • 用户终止的对话
  • 人工智能终止对话
根据这个大纲,我们可以用一些类来构建我们的树。我已经划掉了一些例子,但还没有测试它们。希望它传达了这个想法,您可以构建自己的解决方案。对于您来说,创建一个只知道它是哪种类型的单节点类可能更有用。另一个改进是使用接口或某种方式来概括父/子关系,这将允许更复杂的树结构

class ChoiceNode
{
    public ChoiceNode(ResponseNode myParent)
    {
        parent = myParent;
    }

    ResponseNode parent = null;
    List<ResponseNode> children = new List<ResponseNode>;
    bool canSayGoodbye = true;
}

class ResponseNode
{
    public ResponseNode(ChoiceNode myParent, string myMessage)
    {
        parent = myParent;
        parent.children.Add(this);
        response = myMessage;
    }

    ChoiceNode parent;
    ChoiceNode child;
    string response;
}
类选择节点
{
公共选择区(我的家长负责区)
{
父母=我的父母;
}
responseNodeParent=null;
列表子项=新列表;
bool Cansay再见=真;
}
类响应节点
{
公共响应节点(选择节点myParent,字符串myMessage)
{
父母=我的父母;
parent.children.Add(此);
响应=myMessage;
}
选择端父代;
选秀台儿童;
字符串响应;
}
我们现在应该能够通过简单地枚举ResponseNode.children来使用一种方法来显示对话框选择。然后,每当我们做出对话框选择时,我们都希望显示ResponseNode.response,然后移动到ResponseNode.child以查找下一组对话框选择。当parent==null时,我们处于根分支。当child==null时,我们显示一些终止文本

我希望这是有益的,给你一些想法


好的,我试着理解你代码的逻辑,但有几件事我不明白,也许我最好解释一下我的“统一对话树”

第一: 我们需要创建一个树对象。如果您只需要一个二叉树,您只需要树变量:

public class BinaryTree{
  private string root;
  private BinaryTree left;
  private BinaryTree right
  getters/setters
}
这个对象甚至不需要是Unity组件。 根是“对话” 左边是“optionA” 右边是“选项B” 如果你不需要多个答案,就让左=右。 如果您需要一种方法来识别多个答案,我建议您创建一个如下的对象:

public class Tree{
  private Dictionary<string,string> root;
  private List<Tree> next;
  getters/setters
}
对于树版本,几乎相同:

Start(){
  Tree bn = new Tree();
  bn.Root = new Dictionary<string, string>();
  bn.Root.Add("key1", "Do you need something?");
  bn.Next = new List<Tree>();
  Tree answer1 = new Tree();
  answer1.Root = new Dictionary<string, string>();
  answer1.Root.Add("key2", "Yes");
  bn.Next.Add();
  ... iterate...
}
Start(){
树bn=新树();
bn.Root=新字典();
添加(“键1”,“你需要什么吗?”);
bn.Next=新列表();
树应答器1=新树();
answer1.Root=新字典();
回答1.词根。添加(“键2”,“是”);
bn.Next.Add();
迭代
}
当然,这只是一个基本的例子。初始化的最佳方法是将对话框添加到数组中并进行迭代。 无论如何

现在您可以(例如)创建一个按钮。在开始时,您可以将其文本值初始化为根。在PointerDown/Clicked方法中,您可以创建一个可能答案键的数组,例如,您可以决定为多个答案生成多个按钮(或者只使用2个静态按钮答案和BinaryTree),并根据答案根值(或左/右值)更改文本。在PointerDown/Clicked方法中,每个答案按钮都应该发送用户选择的键值(或左/右对象)(实际上是将在主问题按钮中显示的下一个值)。 当然,再次点击“问题按钮”应该会显示下一个答案(也许你可以决定向你的对象添加一个bool question变量……或者你可以决定只使用问题的左侧……或者你可以决定如果下一个列表中只有一个值,那么这个值就是一个问题,应该只在主按钮文本值中显示)

如果next为null,当然可以结束对话

有多种方法可以做到这一点

Start(){
  BinaryTree bn = new BinaryTree();
  bn.Root = "Is this a question?";
  BinaryTree left = new BinaryTree();
  left.Root = "Nope";
  bn.Left = left;
  BinaryTree right = new BinaryTree();
  right.Root = "Yes it is...";
  bn.Right = right;
}
Start(){
  Tree bn = new Tree();
  bn.Root = new Dictionary<string, string>();
  bn.Root.Add("key1", "Do you need something?");
  bn.Next = new List<Tree>();
  Tree answer1 = new Tree();
  answer1.Root = new Dictionary<string, string>();
  answer1.Root.Add("key2", "Yes");
  bn.Next.Add();
  ... iterate...
}