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

Unity中DontDestroyOnLoad失效求助:场景切换时对象被销毁

问题:Unity场景切换时房间对象被销毁,DontDestroyOnLoad失效

我正在开发一款针对公共场所小区域的GPS应用,地图上的对象代表该区域内的房间位置。我不希望这些对象在切换场景时被销毁,否则需要重新加载到列表中,再从数据库修改它们的名称和颜色。但我无法实现这一点,肯定是哪里操作有误。

我给约300个对象都添加了相同的脚本,代码如下:

private void Awake()
{
    {
        {
            DontDestroyOnLoad(this.gameObject);
            AulaDatabase.addAula(this);
        }
    }
}

我知道每次进入场景对象都会被添加,但问题是它们总会被销毁。我还尝试给所有这些对象的父容器添加另一个脚本,也没有效果。需要说明的是,我在其他对象上使用DontDestroyOnLoad是有效的,请问我哪里做错了?

解决方案

核心问题分析

你遇到的问题不是DontDestroyOnLoad本身失效,而是场景切换时重复加载了房间对象,新加载的对象可能触发了某种逻辑导致旧对象被销毁,或者你没做去重,误以为原来的对象被销毁了。另外你代码里的多层嵌套大括号是冗余的,虽然不影响语法,但可以删掉。

具体修复步骤

  • 给房间对象加唯一标识并做去重
    给每个房间对象分配一个唯一ID(比如从数据库获取的房间编号),在Awake里先检查数据库中是否已存在该对象,避免重复加载:

    public string roomId; // 在Inspector面板或从数据库赋值唯一ID
    
    private void Awake()
    {
        // 检查数据库中是否已有同ID的房间实例
        if (AulaDatabase.HasAula(roomId))
        {
            Destroy(this.gameObject); // 销毁重复加载的对象
            return;
        }
        DontDestroyOnLoad(this.gameObject);
        AulaDatabase.AddAula(roomId, this); // 改用ID作为键存储,方便校验
    }
    
  • 用父容器单例统一管理(更适合批量对象)
    之前给父容器加脚本没效果,大概率是没做单例去重。正确的父容器脚本写法如下:

    1. 将所有房间对象放到一个空物体(命名为RoomContainer)下
    2. 给RoomContainer添加以下脚本:
      public class RoomContainer : MonoBehaviour
      {
          private static RoomContainer _instance;
      
          private void Awake()
          {
              // 单例校验,避免重复加载父容器
              if (_instance != null && _instance != this)
              {
                  Destroy(this.gameObject);
                  return;
              }
              _instance = this;
              DontDestroyOnLoad(this.gameObject);
      
              // 批量注册子房间对象到数据库(做去重)
              foreach (var roomScript in GetComponentsInChildren<YourRoomScript>())
              {
                  if (!AulaDatabase.HasAula(roomScript.roomId))
                  {
                      AulaDatabase.AddAula(roomScript.roomId, roomScript);
                  }
              }
          }
      }
      

    父容器成为单例后,场景切换时不会被销毁,子房间对象会跟着保留,同时避免重复加载整个容器。

  • 检查场景加载与对象状态
    切换场景后,在Unity编辑器的Hierarchy面板里找DontDestroyOnLoad根节点,看看你的房间对象是否在里面:

    • 如果不在,说明Awake方法没执行到——检查脚本是否正确挂载,或者对象是否在Awake前被其他逻辑销毁
    • 如果在,但你还是看不到,可能是新场景的相机设置问题,或者对象被误设为隐藏
  • 排查数据库逻辑
    检查AulaDatabase.addAula方法,看看里面有没有不小心销毁旧对象、移除实例的代码,这也可能导致你误以为对象被场景切换销毁了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 05:03:09