Unity-NullReferenceException при использовании составного шаблона проектирования

Поэтому я пытаюсь создать простое диалоговое дерево в форме составного шаблона проектирования, где каждый член иерархии имеет в основном одинаковые настраиваемые свойства, в данном случае вопрос и два варианта. В 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;
    }
}

1 ответ

Решение

Я думаю, это выглядит довольно просто.

Вы создаете новые экземпляры класса Class, но никогда не устанавливаете Textа также Button имущество.

Эта часть также избыточна, потому что вы говорите ей найти ссылку на себя! ("Текстовое поле" имеет тип Text)

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

Чтобы исправить нулевую ссылку, вы можете сделать поля статическими.

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

И назначить их откуда-то еще. Может быть, скрипт инициализатора с открытыми полями? Вы могли бы сделать много разных вещей. Вот пример, где вы добавляете этот скрипт в пустой игровой объект, затем перетаскиваете текстовое поле / кнопки в слоты инспектора:

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;
Другие вопросы по тегам