我目前正在尝试在游戏结束后重新加载当前场景。
在我的 Unity 场景中,我有一个空的游戏对象,其中有多个
AudioSource
游戏对象:
然后我有另一个名为
AudioService
的游戏对象,它有脚本AudioService.cs
引用了这些AudioService
。没什么特别的:
当我开始游戏/场景时一切正常。
但是,在我重新加载当前场景后:
Debug.Log("[SceneUtil] ReloadCurrentScene");
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
一切似乎都已重新加载,但音频在一段时间后中断。
在
AudioService.Start
我看到音频源确实有参考:
void Start() {
Debug.Log("[AudioService] [Start] Started");
Debug.Log("[AudioService] [Start] audioSourceMusic=" + this.audioSourceMusic);
}
所以,到目前为止一切顺利。
但稍后在游戏中(在我加载所有设置后),引用变为空:
public void onSettingsLoaded()
{
Debug.Log("[AudioService] [onSettingsLoaded] audioSourceMusic=" + this.audioSourceMusic);
this.audioSourceMusic.volume = SettingsService.settings.soundVolumeMusic;
this.audioSourceSFX.volume = SettingsService.settings.soundVolumeSFX;
}
为什么引用在重新加载场景时从
Start
到后来的执行过程中丢失了?
无论如何我可以解决发生的问题吗?
从您的评论中,听起来
onSettingsLoaded
作为监听器附加到一个事件/可观察到的 static
=> 当这个对象由于你的场景重新加载而被卸载/销毁时你忘了删除监听器
=> 调用事件/可观察对象的那一刻,您仍然会触发附加的侦听器,该侦听器属于底层
GameObject
的“无效”实例已经被销毁了-所有其他引用的对象(例如您的AudioSource
s)也是如此
一旦不再需要听众,请始终确保取消订阅。
我不知道你是如何准确地附加听众的,但关于简单的
event
它可能看起来像例如
private void Awake()
{
YourObservedClass.someEvent += Listener;
}
private void OnDestroy()
{
YourObservedClass.someEvent -= Listener;
}
private void Listener()
{
...
}
这样可以保证
Listener
在对象被销毁后不会再被调用