LoadActiveScene() 之后的空引用

null reference after LoadActiveScene()

提问人:linkzandro 提问时间:5/22/2023 最后编辑:derHugolinkzandro 更新时间:6/13/2023 访问量:21

问:

我正在学习 Unity 的基础知识,我正在创建一个脚本,该脚本创建了一个事件并将其发送到另一个称为音频剪辑的脚本

激活事件的函数,在发送事件之前会检查游戏对象标签,然后将 +1 添加到负责计算点数的变量中,销毁玩家与之碰撞的对象并最终激活事件

    public static event EventHandler audioCarrotPlay;

    void OnTriggerEnter2D(Collider2D col){
        switch(col.gameObject.tag){
            case tagColetaveis:
                _controleGame.Pontuacao(1);
                Destroy(col.gameObject);
                audioCarrotPlay?.Invoke(this,EventArgs.Empty);
                
                
                break;

        }

    }

第二个脚本链接到包含 AudioSource 组件的空对象

{
    private AudioSource FxGame;
    [SerializeField]private AudioClip audioCarrot;
    void Start()
    {
        FxGame=gameObject.GetComponent<AudioSource>();
        Debug.Log(FxGame);
        ColetaColetaveis.audioCarrotPlay+=ColetaColetaveis_AudioCrrotPlay;
    }
    

    private void ColetaColetaveis_AudioCrrotPlay(object sender, System.EventArgs e)
    {
        
        Debug.Log("fxgame: "+FxGame);
        FxGame.PlayOneShot(audioCarrot);
        
    }

起初一切顺利,拿起物体时正在播放音频。在那之后,我为玩家实现了一个死亡,当激活时调用 LoadActiveScene() 函数

void CarregaJogo(){
            SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
        }

这时问题就开始了,在第一次生命中一切运行良好,但是在玩家第一次死亡后,unity开始返回nullException,通过debug我发现null对象是FxGame的audiosource,这很奇怪。该对象在第一次调试(我在开始时所做的调试)中不是 null,但是当调用 ColetaColetaveis_AudioCrrotPlay() 函数时,它里面的调试显示现在 FxGame 为 null。

我为此找到的“解决方案”是使 FxGame 静态化private static AudioSource FxGame;

这使得 audioSource 在第一次死亡后工作并且不为 null,但我不希望这个变量是静态的

C# unity-game-engine nullreferenceexception

评论


答:

0赞 linkzandro 5/22/2023 #1

在几个论坛中搜索后,我发现了一些很有希望的东西,当对象被 LoadScene() 销毁时,删除了订阅者的注册。

void OnDestroy(){
    ColetaColetaveis.audioCarrotPlay-=ColetaColetaveis_AudioCrrotPlay;
}

这个函数在物体被破坏时删除铭文,显然这就是问题所在,因为物体不再是空的,并且触发了声音效果