使用复合设计模式时出现 Unity-NullReferenceException

Unity-NullReferenceException When Using Composite Design Pattern

所以我尝试以复合设计模式的形式制作一个简单的对话树,其中层次结构的每个成员都具有基本相同的可自定义属性,在本例中为一个问题和两个选项。在 Unity 中,我试图将问题分配给一个文本框,并将每个选项分配给一个按钮。当您单击一个按钮时,您会转到树的另一层或一片叶子。无论出于何种原因,我收到空引用异常错误并指向这一行。我会尽力回答任何进一步的问题。

        Textbox.GetComponent<Text>().text = question;

这可能是我可以解决的简单问题,但我不确定现在该去哪里找。如果有人能在正确的方向上帮助我,我将不胜感激。谢谢你。这是我在复合模式中的关卡脚本。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class Composite : MonoBehaviour {


    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 class Level
    {
        public static Text Textbox;
        public static Text Button1;
        public static Text 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;


            Textbox.GetComponent<Text>().text = Question;
            Button1.GetComponent<Text>().text = OptionA;
            Button2.GetComponent<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;
        }

    }

}

初始化脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Initializer : MonoBehaviour {

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

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

我认为它看起来很简单。

您正在创建级别 Class 的新实例,但从未设置 TextButton 属性。

这部分也是多余的,因为你是在告诉它自己找一个引用! ("Textbox" 属于 Text 类型)

Textbox.GetComponent<Text>()....

要修复空引用,您可以将字段设为静态。

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

并从其他地方分配它们。也许是带有 public 字段的初始化脚本?你可以做很多不同的事情。 这是一个示例,您将此脚本添加到一个空的游戏对象,然后将文本框/按钮拖到检查器插槽中:

public class Initializer : MonoBehaviour
{
   public Text Textbox;
   public Button Button1;
   public Button Button2;

 // Awake is called before Start, so Start() in your Composite script will be called 
 // after these fields have been initialized
   void Awake() 
   {
      Level.Textbox = this.Textbox;
      Level.Button1 = this.Button1;
      Level.Button2 = this.Button2;
   }
}

最后删除这些注释行,它们完全一样。

    // Textbox.GetComponent<Text>().text = question;
    Textbox.text = question;
    Button1.GetComponent<Text>().text = optionA;
    // Button1.text = optionA;
    Button2.GetComponent<Text>().text = optionB;
    // Button2.text = optionA;