我的选项菜单中有2个按钮,“返回主菜单”和“静音” 这些按钮中的每个按钮都附有脚本,并在按下脚本时调用脚本的OnPress()方法。 我还有一个主要的Level对象/脚本,可以处理所有场景加载和填充。 因此,主菜单按钮的脚本在其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'类型的对象已被破坏,但您仍在尝试访问它。 您的脚本应检查其是否为null或不破坏该对象。 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)
感谢您的时间:)
答案 0 :(得分:0)
确定执行该问题的确切顺序可能有点困难,但是您丢失了Start()中由Awake()处理的引用这一事实很奇怪。过去,我在Start()中使用FindObjectOfType<>
时遇到了问题,所以也许最好改变一下处理单例的方式。
我建议您使您的等级 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);
}
这将导致它一次创建一个Level类,然后销毁它的所有后续版本(例如,当您重新加载放置它的场景时)。
现在,要在其他脚本中引用它,则无需再次使用FindObjectOfType<Level>()
!您可以像这样静态引用Level.instance
:
//New way to call ToggleMuteMusic()
Level.instance.ToggleMuteMusic();
希望这会有所帮助!