Unity Объект типа "GameObject" был уничтожен - PullRequest
0 голосов
/ 25 октября 2019

В моем меню параметров есть 2 кнопки: «вернуться в главное меню» и «отключить музыку». К каждой из этих кнопок прикреплен скрипт, и при нажатии вызывается метод скрипта OnPress (). У меня также есть основной объект / скрипт уровня, который обрабатывает загрузку сцены и прочее. Таким образом, скрипт кнопки главного меню выполняет FindObjectOfType () в своем Start, а затем вызывает level.LoadStartScene () в своем OnPress (). Сценарий для кнопки отключения звука делает то же самое, но вызывает level.ToggleMuteMusic (). Раньше это прекрасно работало, но потом я сделал уровень синглтоном со следующим кодом:

public void Awake() {
    InitializeSingleton();
}

private void InitializeSingleton() {
    if (FindObjectsOfType(GetType()).Length > 1) {
        Destroy(gameObject);
    } else {
        DontDestroyOnLoad(gameObject);
    }
}

Так что теперь кнопка главного меню работает отлично, но кнопка отключения звука выдает ошибку;Я думаю, это потому, что в Start () он находит старый объект уровня, а затем входит тот, который с DontDestroyOnLoad, и удаляет старый, но тогда почему кнопка главного меню работает ???

Кнопка отключения звукаКод:

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

public class MuteButton : MonoBehaviour {

[SerializeField] string mutedText = "Unmute Music";
[SerializeField] string unmutedText = "Mute Music";

private Level level;
private TextMeshProUGUI myText;

public void Start() {
    level = FindObjectOfType<Level>();
    myText = GetComponent<TextMeshProUGUI>();
}

public void OnPress() {
    if (level == null) {
        Debug.Log("log 1");
    }
    level.ToggleMuteMusic();
    bool muteMusic = level.GetMuteMusic();
    if (muteMusic == true) {
        myText.SetText(mutedText);
    } else if (muteMusic == false) {
        myText.SetText(unmutedText);
    }
}

}

Код кнопки меню:

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

public class MenuButton : MonoBehaviour {

Level level;

public void Start() {
    level = FindObjectOfType<Level>();
}

public void OnPress() {
    level.LoadStartScene();
}
}

Полная ошибка:

MissingReferenceException: объект типа 'GameObject' был уничтожен, но вы все еще пытаетесьчтобы получить к нему доступ. Ваш сценарий должен либо проверить, является ли он нулевым, либо вы не должны уничтожать объект. UnityEngine.GameObject.GetComponent [T] () (в C: /buildslave/unity/build/Runtime/Export/Scripting/GameObject.bindings.cs: 28) Level.ToggleMuteMusic () (в Assets / Scripts / Level.cs:74) MuteButton.OnPress () (в разделе Активы / Сценарии / MuteButton.cs: 23)

Спасибо за ваше время:)

1 Ответ

0 голосов
/ 25 октября 2019

Может быть немного трудно определить точный порядок выполнения задач, чтобы вызвать эту проблему, но тот факт, что вы теряете ссылку в Start (), которая была обработана в Awake (), является странным. У меня были проблемы с использованием FindObjectOfType<> в Start () в прошлом, поэтому, возможно, лучше было бы изменить способ обработки одиночного файла.

Что бы я порекомендовал, это сделать ваш уровень static, чтобы вы могли легче ссылаться на него, поскольку вы уже внедрили форму Singleton.

Вот пример того, как вы можете переписать верхнюю часть вашего файла Level.cs:

public static Level instance;

private void Awake()
{
    if (instance != null && instance != this)
    {
        Destroy(this.gameObject);
        return;
    }
    else
    {
        instance = this;
    }
    DontDestroyOnLoad(this.gameObject);
}

Это заставляет его создать класс Уровня один раз, а затем уничтожить все последующие версии (например, когда вы перезагружаете сцену, в которой он находится).

Теперь, чтобы ссылаться на него в других ваших скриптахВам больше никогда не придется использовать FindObjectOfType<Level>()! Вы можете статически ссылаться на Level.instance, например так:

//New way to call ToggleMuteMusic()
Level.instance.ToggleMuteMusic();

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...