关于DontDestroyOnLoad的一点笔记

关于DontDestroyOnLoad的一点笔记

由于Unity中实例化GameObject的代价是比较高的,所以项目利用DontDestroyOnLoad做了一个可重复回收再利用的东西,关键代码是:Instantiate预设之后,调用DontDestoryOnLoad来包装一次,并且用一个列表List来保存这个物体的引用,当物体不再使用时,使用transform.SetParent(null,false)来隐藏掉.最后在这个界面被OnDestroy时,手动Destroy掉List里的每一个物体.

抛开设计思路不谈,问题是当游戏切换场景时,会抛出错误,虽然不影响实际游戏,但毕竟是个Error:MissingReferenceException: The object of type 'AppComment' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.

这显然是物体被Destroy了两次,意味着在场景被Unload的时候物体已经被摧毁了,然后再次在脚本里Destroy的时候就报错了.怎么回事呢?很久之前在看这个问题了,今天又在网上查了半天,原来是当GameObject被使用后,会破坏掉DontDestroyOnLoad的标记.在Editor里面我们可以在DontDestroyOnLoad场景追踪到所有被标记为DontDestroyOnLoadGameObject,但在物体被使用时,肯定会将它的Parent设定为当前活跃场景的一个对象,所以DontDestroyOnLoad的标签就被打破了.

具体的可以可以看Unity论坛的问题:撤销DontDestroyOnLoad.

另外关于一点DontDestroyOnLoad场景的说明:DontDestroyOnLoad并不是一个场景,通过SceneManager获取到的会是一个Invalid Scene,你也无法通过GetRootGameObjects来获取该场景的所有跟物体.这个场景仅仅是为了方便在Editor中检视带有DontDestroyOnLoad标记的物体而存在的,而在Runtime中是不存在的.Unity手册中可以找到关于这些的描述:Play mode部分.

如果需要通过找场景的方式来获取所有带有DontDestroyOnLoad标记的物体,可以通过一个小科技,具体查看链接的回答(没试验过):
获取所有DontDestroyOnLoad物体,并且按照外国友人的说法,这个黑科技也只在Editor中有效.

原文地址:https://www.cnblogs.com/Fallever/p/10140868.html