You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity游戏C#代码问题:场景切换后攻击怪物触发MissingReferenceException

问题修复方案

核心原因

场景切换时Unity会销毁旧场景内所有未标记DontDestroyOnLoad的对象,返回原场景后生成的怪物是全新实例。但你的melee触发器逻辑或enemyMove脚本仍持有旧怪物的SpriteRenderer引用,导致访问已销毁对象触发异常。

具体修复步骤

1. 检查并清理触发器中的无效引用

在melee脚本的OnTriggerEnter2D方法中,每次触发时先验证目标对象及组件的有效性:

private void OnTriggerEnter2D(Collider2D other)
{
    if (other == null || !other.gameObject.activeInHierarchy)
        return;

    enemyMove enemy = other.GetComponent<enemyMove>();
    if (enemy == null)
        return;

    if (enemy.GetComponent<SpriteRenderer>() != null)
    {
        enemy.setDmg(attackDamage);
    }
}

2. 加固enemyMove的setDmg方法

在setDmg方法中增加对SpriteRenderer的有效性检查,避免访问已销毁对象:

public void setDmg(int damage)
{
    SpriteRenderer sr = GetComponent<SpriteRenderer>();
    if (sr == null)
        return;

    // 原有伤害逻辑
    currentHealth -= damage;
    sr.color = Color.red;
    // ...其他业务代码
}

3. 场景切换时清理遗留引用与订阅

如果脚本使用了事件订阅、协程或持久化对象,需在OnDestroy中做清理:

private void OnDestroy()
{
    // 取消所有事件订阅(示例)
    // EventManager.OnPlayerAttack -= HandleAttack;
    StopAllCoroutines();
}

4. 跨场景引用重置

如果有DontDestroyOnLoad标记的对象(如玩家、UI管理器)持有旧场景怪物的引用,需在场景加载完成时重置:

private void OnEnable()
{
    SceneManager.sceneLoaded += OnSceneLoaded;
}

private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
    // 重置所有可能持有旧场景对象的引用
    // 例如:targetEnemy = null;
}

private void OnDisable()
{
    SceneManager.sceneLoaded -= OnSceneLoaded;
}

额外排查点

  • 检查是否有协程在对象销毁后仍执行,需在OnDestroy中停止。
  • 避免在Update/FixedUpdate中直接访问可能被销毁的对象,每次访问前做有效性检查。

内容的提问来源于stack exchange,提问作者뭉게뭉개

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 09:45:17