Unity: NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта с несколькими операторами gameObject.SetActive - PullRequest
0 голосов
/ 29 января 2019

Я столкнулся с этой ошибкой при попытке скрыть игровой объект, это панель.Панель содержит холст и две кнопки.

Изначально панель скрыта и скрипт работает.Ошибка возникает, когда я пытаюсь снова включить panel.SetActive (true) и вернуться к панели. SetActive (false).

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class EquipmentSlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
    public GameObject panel;

    void Start()
    {
       GameObject panel= GameObject.FindGameObjectWithTag("panel");
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        GameObject panel= GameObject.FindGameObjectWithTag("panel");
        panel.SetActive(false);
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        GameObject panel = GameObject.FindGameObjectWithTag("panel");
        panel.SetActive(true);
    }
}

Я удалил ненужный код.Мне бы хотелось, чтобы панель открывалась и закрывалась при наведении курсора на элемент меню, и чтобы вы знали, функции наведения работают в моем коде.

1 Ответ

0 голосов
/ 29 января 2019

Проблема

FindGameObjectWithTag, которая равна afaik GameObject.FindWithTag в новых версиях, не находит объекты, которые неактивны!

Возвращает один тег active GameObject.Возвращает null, если не было найдено GameObject.

Поэтому после установки значения SetActive(false) вы не сможете найти его снова, используя любой из вариантов Find.

Кроме того, вы создаете новую локальную переменную с именем panel каждый раз, скрывая уже существующую panel вместо того, чтобы использовать уже имеющуюся.

Solution

Так что вместо этогополучить ссылку, пока объект активен и только один раз, и использовать ее позже:

public class EquipmentSlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler/*, IPointerDownHandler, IPointerUpHandler*/
{
    // if you referenced this in the Inspector e.g. via drag & drop
    // you could completely skip the Find in the start method
    public GameObject panel;

    void Start()
    {
       panel = GameObject.FindGameObjectWithTag("panel");
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        panel.SetActive(false);
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        panel.SetActive(true);
    }
}

(Конечно, если объект был уничтожен, это все равно даст вам исключение.)

...