Создание списка действий UnityActions и их назначение кнопкам - PullRequest
0 голосов
/ 18 июня 2020

Я работаю над игрой про магната и хочу иметь несколько вариантов для каждого здания, на которое может щелкнуть игрок. В магазине должна быть возможность есть, инвестировать и выкупить, в то время как в офисе должно быть что-то вроде работы, разговора с менеджером и т. Д. c. Для этого я создал одну панель для параметров и создал количество параметров для каждого здания из списка строк, который создает экземпляр кнопки для каждой строки и присваивает текст кнопки этой конкретной строке как таковой:

public override void Interact()
{
    Debug.Log(type);
    SetUpFunctions(activites);
}

public void SetUpFunctions(List<string> activs)
{
    foreach (string item in activs)
    {
        optionsUI.AddOption(item);
    }
}

Перечень работ задается в инспекторе. Этот метод отлично работает и присваивает каждой строке действия тексту кнопки. Однако всем созданным кнопкам назначена одна и та же функция, поэтому я решил сделать то же самое со списком методов и назначить их каждой кнопке, как я сделал со строками:

[HideInInspector]public List<UnityAction> functions; //list of functions tied to each activity


public override void Interact()
{
    Debug.Log(type);
    functions.Add(Eat);
    functions.Add(Work);
    functions.Add(StopWork);
    SetUpFunctions(activites, functions);
}

public void SetUpFunctions(List<string> activs, List<UnityAction> funcs)
{
    //foreach (string item in activs)
    //{
    //    optionsUI.AddOption(item);
    //}
    var col = activs.Zip(funcs, (x, y) => new { X = x, Y = y });//combine the two lists as one
    foreach (var entry in col)
    {
        optionsUI.AddOption(col.X, col.Y);//Assign the activity name and function
    }

}

 public void Eat() 
{
    Debug.Log("Player is eating");
} 
public void Work() 
{
    Debug.Log("Player is Working");
} 
public void StopWork() 
{
    Debug.Log("Player Stopped Working");
}



 //From the OptionsUI script
 public void AddOption(string optionName, UnityAction optionFunc)
{
    OptionUIItem emptyOption = Instantiate(itemProfile, scrollViewContent);
    emptyOption.transform.SetParent(scrollViewContent);
    emptyOption.SetupOption(optionName, optionFunc);
}


//The script assigned to each button created
public class OptionUIItem : MonoBehaviour
{
    public Text text;
    public Button btn;

    public void SetupOption(string name, UnityAction func)
    {
        text.text = name;
        btn.onClick.AddListener(func);
    }

    public void OnOptionSelect()
    {
        Debug.Log("Option selected");
    }
}

Однако, когда я пытаюсь сделать это таким образом, я получаю исключение NullReferenceException для первой функции. Add (Eat);

Мой вопрос:

  1. Возможно или даже правильно это сделать таким образом?
  2. Если да, то как мне решить эту проблему, чтобы назначить каждую функцию в списке каждой созданной кнопке и
  3. любые другие методы, которые могут быть лучше для этого, например, используя словарь?

Спасибо.

1 Ответ

0 голосов
/ 18 июня 2020

Если вы скрываете поле в Инспекторе, оно не автоматически инициализируется (только сериализованные поля), поэтому NullReferenceException при попытке Add что-то к нему.

Обязательно сделать это уже вместе с декларацией

public List<UnityAction> functions = new List<UnityAction>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...