【发布时间】:2020-02-22 02:47:30
【问题描述】:
我的选项菜单中有 2 个按钮,“返回主菜单”和“静音音乐” 这些按钮中的每一个都附有一个脚本,并在按下时调用脚本的 OnPress() 方法。 我还有一个主要的关卡对象/脚本来处理所有的场景加载和东西。 因此,主菜单按钮的脚本在其 Start 中执行 FindObjectOfType(),然后在其 OnPress() 中调用 level.LoadStartScene()。 静音按钮的脚本做同样的事情,但调用 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 () (在 Assets/Scripts/MuteButton.cs:23)
感谢您的宝贵时间 :)
【问题讨论】:
-
这个实现不是单例模式。单例确保一个类只有 1 个且只有 1 个实例。您只是告诉系统在加载新场景时不要销毁此对象。您的代码中没有任何内容可以阻止创建另一个实例。因此,最有可能发生的是正在创建该类的第二个实例,并且它在 InitializeSingleton 中通过 (FindObjectsOfType(GetType()).Length > 1) 为“真”而破坏自身。为什么需要单例?
-
作为附加说明,可以在此处找到单例模式的良好实现:wiki.unity3d.com/index.php/Singleton。我用过这个,效果很好。