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

使用DontDestroyOnLoad()函数时如何访问场景中的其他脚本?

DontDestroyOnLoad 跨场景脚本访问实现方案

首先修正你代码中的基础错误:

  • API拼写错误:你写的Dondestroy不存在,正确接口为DontDestroyOnLoad()
  • 调用时需保证脚本挂载在场景根物体上,若挂载在父物体下的子物体,会随父物体销毁被清除,无法实现常驻。

核心问题原因

标记了DontDestroyOnLoad的物体是跨场景常驻对象,场景切换时,新场景内的所有物体是在加载流程完成后才完成初始化的,如果你在常驻脚本的Awake/Start生命周期里直接查找场景内脚本,会因为时序问题查找到空引用。

可行实现方案

  • 方案1:监听场景加载完成事件,待场景初始化完毕后再查找目标脚本
    这是最稳妥的主动查找方案,不会出现时序问题,参考代码:
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public class PersistentNode : MonoBehaviour
    {
        // 单例实例,方便其他脚本反向访问常驻物体
        public static PersistentNode Instance;
        private SceneTargetScript _targetScript;
    
        void Awake()
        {
            // 处理重复常驻的问题
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
                return;
            }
            Instance = this;
            // 正确调用常驻接口
            DontDestroyOnLoad(gameObject);
            // 注册场景加载完成监听
            SceneManager.sceneLoaded += OnNewSceneLoaded;
        }
    
        private void OnNewSceneLoaded(Scene scene, LoadSceneMode loadMode)
        {
            // 场景加载完成后,所有场景物体已初始化,此时查找不会为空
            _targetScript = FindObjectOfType<SceneTargetScript>();
            if (_targetScript != null)
            {
                // 找到后可直接调用目标脚本的方法、访问属性
                _targetScript.BindPersistentNode(this);
            }
        }
    
        void OnDestroy()
        {
            // 销毁时注销监听,避免内存泄漏
            SceneManager.sceneLoaded -= OnNewSceneLoaded;
        }
    }
    
  • 方案2:反向通信,让场景内脚本主动访问常驻对象
    这是更解耦的实现方式,不需要常驻物体主动查找场景对象,场景脚本在自身生命周期内主动访问常驻物体的单例即可,参考场景脚本代码:
    public class SceneTargetScript : MonoBehaviour
    {
        void Start()
        {
            // 场景脚本初始化时,直接访问常驻物体单例完成通信
            if (PersistentNode.Instance != null)
            {
                PersistentNode.Instance.RegisterTarget(this);
            }
        }
    }
    
  • 方案3:固定引用挂载(不推荐大规模使用)
    对于固定位置的核心场景对象,可以在场景加载完成后,通过指定Tag、或者提前挂载引用的方式访问,灵活性较差,仅适合小型项目固定流程使用。

注意事项

  • 禁止在常驻物体的Awake/Start生命周期中直接查找非常驻场景对象,必然会因为加载时序问题返回空
  • 不要每帧调用FindObjectOfType系列接口查找对象,性能开销极高,查找一次后缓存引用即可
  • 若常驻物体需要管理多个场景对象,建议搭配事件系统实现通信,减少硬引用依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 06:51:37