Unity3D单例模式问题:多GameSession对象为何全部消失?
问题描述
代码片段
[SerializeField] int playerLives = 3; void Awake() { int numGameSessions = FindObjectsOfType<GameSession>().Length; if(numGameSessions > 1) { Destroy(gameObject); } else { DontDestroyOnLoad(gameObject); } }
场景现象
- 层级面板中仅放置1个GameSession对象时,
DontDestroyOnLoad生效,游戏运行正常。 - 场景中放置3个GameSession对象时,所有对象均被销毁,
DontDestroyOnLoad完全未生效。
问题解答
核心原因是所有GameSession对象的Awake方法执行时,场景内的同类型对象已全部实例化:
当场景里存在3个GameSession对象时,它们的Awake会在同一帧内依次执行。每个对象调用FindObjectsOfType<GameSession>()时,都会得到当前场景中所有已创建的同类型对象总数——也就是3。因此每个对象都会触发numGameSessions > 1的判断,执行Destroy(gameObject),最终所有对象都被销毁,自然没有对象能进入DontDestroyOnLoad的分支。
修复方案
改用静态变量标记已存在的单例实例,避免依赖FindObjectsOfType的实时计数:
[SerializeField] int playerLives = 3; private static GameSession _instance; void Awake() { // 若已有实例存在,直接销毁当前对象 if (_instance != null) { Destroy(gameObject); return; } // 将当前对象设为全局单例,并标记不随场景销毁 _instance = this; DontDestroyOnLoad(gameObject); }
这个逻辑下,第一个执行Awake的对象会成为留存的单例,后续对象都会被直接销毁,保证始终只有一个GameSession实例生效。
内容的提问来源于stack exchange,提问作者Đỗ Trọng Khoa
相关产品推荐
相关产品推荐

