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

如何解决使用DontDestroyOnLoad后重载场景时GameObject重复问题?

解决Unity关卡切换时重复生成保留对象的问题

核心问题是:用DontDestroyOnLoad保留的对象不会随场景销毁,但重新加载场景时,场景内的原始对象会被再次实例化,导致多个相同对象共存。用单例模式就能简单解决这个问题,确保每个需要保留的对象只有一个实例存在。

具体实现步骤

1. 创建通用持久化脚本

给需要跨场景保留的对象(比如玩家)挂一个脚本,命名为PersistentObject.cs,代码如下:

using UnityEngine;

public class PersistentObject : MonoBehaviour
{
    // 静态变量,存储该类型对象的唯一实例
    private static PersistentObject _instance;

    void Awake()
    {
        // 检查是否已经存在实例
        if (_instance != null && _instance != this)
        {
            // 如果已有实例,直接销毁当前新生成的重复对象
            Destroy(gameObject);
        }
        else
        {
            // 如果没有实例,将自己设为唯一实例,并标记为不随场景销毁
            _instance = this;
            DontDestroyOnLoad(gameObject);
        }
    }
}

2. 代码逻辑解释

  • _instance是静态变量,整个游戏生命周期中只会有一份,用来记录第一个被创建的保留对象。
  • Awake()是Unity对象初始化时最先调用的方法,适合在这一步做实例检查:
    • 当重新加载场景时,场景里的玩家对象会被重新创建,此时_instance已经指向之前保留的那个对象,所以新生成的对象会被直接销毁。
    • 如果是第一次加载场景,_instance为空,就把当前对象设为实例,并通过DontDestroyOnLoad保留它。

3. 可选:场景加载后重置状态(比如玩家位置)

如果需要在场景加载完成后重置对象状态(比如把玩家放到出生点),可以添加场景加载事件监听,修改后的代码如下:

using UnityEngine;
using UnityEngine.SceneManagement;

public class PersistentObject : MonoBehaviour
{
    private static PersistentObject _instance;

    void Awake()
    {
        if (_instance != null && _instance != this)
        {
            Destroy(gameObject);
        }
        else
        {
            _instance = this;
            DontDestroyOnLoad(gameObject);
            // 注册场景加载完成的回调事件
            SceneManager.sceneLoaded += OnSceneLoaded;
        }
    }

    // 场景加载完成时自动调用
    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        // 示例:找到场景中的出生点,重置玩家位置
        Transform spawnPoint = GameObject.Find("SpawnPoint").transform;
        if (spawnPoint != null)
        {
            transform.position = spawnPoint.position;
        }
    }

    void OnDestroy()
    {
        // 销毁对象时取消事件注册,避免内存泄漏
        SceneManager.sceneLoaded -= OnSceneLoaded;
    }
}

注意事项

  • 每个需要跨场景保留的对象(比如全局UI、音效管理器)都可以挂这个脚本,确保各自只有一个实例。
  • 不要手动在代码里重复实例化这些对象,让场景加载时自动生成即可,脚本会自动处理重复情况。

内容的提问来源于stack exchange,提问作者Business Cactus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:35:18