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;