首页 > 解决方案 > 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()
 {

 }

}

public class Initializer : MonoBehaviour {

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

void Awake()
{
    Level.Textbox = this.Textbox;
    Level.Button1 = this.Button1;
    Level.Button2 = this.Button2;
}
}

标签: unity3ddialogcomposite

解决方案


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


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

  • 做出对话选择(说话)
  • 观察对话响应(聆听)

我们还需要考虑一些重要的条件:

  • 用户终止的对话
  • 人工智能终止对话

从这个大纲中,我们可以用一些类来构建我们的树。我已经划出了一些例子,但我还没有测试过它们。希望它传达了这个想法,您可以构建自己的解决方案。对你来说,创建一个只知道它是哪种类型的单个 Node 类也可能更有用。另一个改进是使用接口或某种方式来概括父/子关系,这将允许更复杂的树结构。

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;
}

我们现在应该能够通过简单地枚举 ResponseNode.children 来使用一种方法来显示对话框选择。然后,每当我们做出对话选择时,我们都希望显示 ResponseNode.response,然后移动到 ResponseNode.child 以查找下一组对话选择。当 parent == null 时,我们位于根分支。当 child == null 我们显示一些终止文本。

我希望这对您有所帮助并给您一些想法。

树形数据结构图


推荐阅读