简体   繁体   中英

Why can't my function access a private variable INSIDE of the class it's in?

EDIT: I'm not confused about what a null error indicates, I know that my list is null. I'm just unsure of why it would be null in this case, or why setting my list to public suddenly fixes this.

So, I'm trying to make a function that will add an object to a list if it meets the conditions. The function takes in the tag it's checking for, and the specific list it'll add it to if possible. The reason I'm doing this, is because I have two lists, and I'd rather only need one function for both.

This works all well and good, but I'm having an issue where it doesn't...really seem to work unless the lists are set to public? Which I'd rather not do if I can help it. I don't understand why, since it handles the private gameObject reference just fine, and that's declared in the same spot, and the function is inside the same class, yet trying to call this function while the lists are private just gives me a null object reference error, which I've narrowed down to the list being null in this case, not the object?

This isn't really a big deal, since I can just change around a few things to avoid having the lists public, but I'm just really confused as to why this is happening? I've tried explicitly passing by ref, but that gave the same issues.

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;
                }
            }

        }
    }

Output of this code:

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)

And I know the object isn't what's null in this case, because I had a debug log print the object. It's there.

Since your lists are nonpublic and also nonserialized fields you can't assign them from inspector to create new list instance automaticaly, so in your ClickHandler script add Awake method where you instantiate them as new list objects.

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

or you can do same thing at declaration time

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM