繁体   English   中英

Unity “GameObject”类型的 object 已被销毁

[英]Unity The object of type “GameObject” has been destroyed

我的选项菜单中有 2 个按钮,“返回主菜单”和“静音音乐”每个按钮都附有一个脚本,并在按下时调用脚本的 OnPress() 方法。 我还有一个主要的关卡对象/脚本来处理所有的场景加载和东西。 因此主菜单按钮的脚本在其 Start 中执行 FindObjectOfType(),然后在其 OnPress() 中调用 level.LoadStartScene()。 静音按钮的脚本做同样的事情,但调用 level.ToggleMuteMusic()。 所以这之前工作得很好,但后来我使用以下代码制作了 singleton 级别:

public void Awake() {
    InitializeSingleton();
}

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

所以现在主菜单按钮可以正常工作,但是静音按钮会出错; 我认为这是因为在 Start() 中它找到了旧级别 object,然后带有 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”类型的 object 已被破坏,但您仍在尝试访问它。 您的脚本应该检查它是否是 null,或者您不应该破坏 object。 UnityEngine.GameObject.GetComponent[T] () (at C:/buildslave/unity/build/Runtime/Export/Scripting/GameObject.bindings.cs:28) Level.ToggleMuteMusic () (at Assets/Scripts/Level.cs: 74) MuteButton.OnPress () (在 Assets/Scripts/MuteButton.cs:23)

谢谢你的时间:)

你能展示你的脚本的全部代码吗? :) 这将有助于理解。

确定导致此问题的事物执行的确切顺序可能有点困难,但是您在 Start() 中丢失了在 Awake() 中处理的引用这一事实很奇怪。 过去我在 Start() 中使用FindObjectOfType<>时遇到过问题,因此最好改变您处理 singleton 的方式。

我建议您制作您的级别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);
}

这会导致它创建关卡 class 一次,然后销毁它的所有后续版本(例如重新加载它所在的场景时)。

现在,要在其他脚本中引用它,您再也不必使用FindObjectOfType<Level>()了! 您可以静态引用Level.instance ,如下所示:

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

希望这会有所帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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