Почему моя функция не может получить доступ к закрытой переменной INSIDE класса, в котором она находится? - PullRequest
0 голосов
/ 18 апреля 2020

РЕДАКТИРОВАТЬ: меня не смущает, что означает нулевую ошибку, я знаю, что мой список пуст. Я просто не уверен, почему в этом случае он будет нулевым или почему установка моего списка на publi c внезапно исправит это.

Итак, я пытаюсь создать функцию, которая будет добавлять объект в список, если он соответствует условиям. Функция берет тег, для которого она проверяет, и список спецификаций c, к которому она будет добавлена, если это возможно. Причина, по которой я это делаю, заключается в том, что у меня есть два списка, и мне скорее всего понадобится только одна функция для обоих.

Это работает хорошо, но у меня возникла проблема, когда кажется ... действительно работает, если списки не установлены на publi c? Что я бы предпочел не делать, если смогу помочь. Я не понимаю, почему, так как он прекрасно обрабатывает частную ссылку на gameObject, и она объявлена ​​в том же месте, и функция находится внутри того же класса, но попытка вызвать эту функцию, пока списки закрыты, просто дает мне ноль Ошибка ссылки на объект, которая в данном случае сузилась до нуля, а не объекта?

Это не такая уж большая проблема, поскольку я могу просто изменить несколько вещей, чтобы избежать списки публикуются c, но я просто не понимаю, почему это происходит? Я попытался явно передать ref, но это дало те же проблемы.

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

public class ClickHandler : MonoBehaviour
{
    GameObject clickedMob = null;

    List<GameObject> selectedMinions;
    List<GameObject> selectedHostiles;

    void Update ( )
    {

        if ( Input.GetButtonDown("Click"))
        {
            switch (clickState)
            {
                case NextClickAction.Nothing:
                    { }
                    break;

                case NextClickAction.TargetFriendly:
                    {

                       hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);

                        if ( hit )
                        {
                            if ( hit.transform != null )
                            {
                                clickedMob = hit.transform.gameObject;
                                CheckObject("Minion", selectedMinions);
                            }
                        }
                    }
                    break;

                case NextClickAction.TargetHostile:
                    {
                        hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);

                        if ( hit )
                        {
                            if ( hit.transform != null )
                            {
                                clickedMob = hit.transform.gameObject;
                                CheckObject("Hostile", selectedHostiles);
                            }
                        }
                    }
                    break;

                default:
                    {
                        Debug.Log("why do you have an enum this big");
                        DeactivateClick();
                        Debug.LogError("Enum set outside of index. Returned to 0.");
                        break;
                    }
            }

        }
    }   //  end of update

    private void CheckObject ( string tag , List<GameObject> mobList)
    {
        if ( clickedMob.CompareTag(tag) )
        {
            if ( clickedMob.GetComponent<Animator>() != null )
            {
                ClickedMobAnimator = clickedMob.GetComponent<Animator>();

                switch (ClickedMobAnimator.GetBool("Selected"))
                {
                    case true:
                        ClickedMobAnimator.SetBool("Selected", false); // Setting the object to have a little box around it when it's selected.

                        mobList.Remove(clickedMob);
                        Debug.Log(mobList.Count + " " + clickedMob);
                        break;

                    case false:
                        ClickedMobAnimator.SetBool("Selected", true);
                        mobList.Add(clickedMob); 
                        Debug.Log(mobList.Count + " " + clickedMob);
                        break;
                }
            }

        }
    }

Вывод этого кода:

NullReferenceException: Object reference not set to an instance of an object
ClickHandler.CheckObject (System.String tag, System.Collections.Generic.List'[T] mobList) (at Assets/Scripts/ClickHandler.cs:119)

И я знаю, что объект не равен нулю в этот случай, потому что у меня был журнал отладки распечатать объект. Это там.

1 Ответ

1 голос
/ 19 апреля 2020

Поскольку ваши списки неопубликованные c, а также несериализованные поля, вы не можете назначать их из инспектора для автоматического создания нового экземпляра списка, поэтому в вашем скрипте ClickHandler добавьте метод Awake, в котором вы создаете его экземпляры как новые объекты списка.

void Awake() {
    selectedMinions = new List<GameObject>();
    selectedHostiles = new List<GameObject>();
}

или вы можете сделать то же самое во время объявления

List<GameObject> selectedMinions = new List<GameObject>();
List<GameObject> selectedHostiles = new List<GameObject>();
...