Unity中的一个方法DontDestroyOnLoad可以让某些游戏对象在切换场景的时候不是施放,听起来是一个非常好的方法,但是其实如果没用好那么可能就是有问题了。
举个例子:
在场景1中某一个脚本的Start方法中,DontDestroyOnLoad(A)
接着切换到场景2中,理所当然A对象被保留了下来
如果在从2场景再次回到1场景,那么又执行了一遍DontDestroyOnLoad(A)然而之前你的A对象却没有被施放,这样就会无线循环下去了。
当然我们可以去做逻辑判断是否DontDestroyOnLoad,判断A是否等于Null做一些判断。但是我觉得这其实是下策。DontDestroyOnLoad方法其实更多的是去保存一个全局的游戏脚本,比如一些第三方的SDK你需要用这个脚本来做中间件的支持。
我目前的做法是,我做了一个初始化场景。在初始化场景里面我只做两件事,第一在初始化场景里面的某个游戏对象的全局脚本中,Start方法里我把这个场景里面的所有游戏对象全部设置成DontDestroyOnLoad,也就是切换场景时不销毁,比如NGUI的Root梳妆结构。
1 2 3 4 5 6 |
Object[] initsObjects = GameObject.FindObjectsOfType(typeof(GameObject)); foreach (Object go in initsObjects) { DontDestroyOnLoad(go); } |
第二,接着我在进入我的第一个游戏场景,也就是说我的逻辑永远不会在回返我的初始化场景。所以我也不会出现来回切场景DontDestroyOnLoad没有删除的问题。
还有一个巧妙的办法就是利用static 初始化方法,如下代码所示,当代码在调用Global类的时候
首先程序会进入static Global方法中,这个方法永远只会走一遍,所以我在这里创建一个GameObjcet,然后把Global这条脚本绑定上去,我在DontDestroyOnLoad这个对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using UnityEngine; using System.Collections; public class Global :MonoBehaviour { public static Global instance; static Global() { GameObject go = new GameObject("Globa"); DontDestroyOnLoad(go); instance = go.AddComponent<Global>(); } public void DoSomeThings() { Debug.Log("DoSomeThings"); } void Start () { Debug.Log("Start"); } } |
这样这条脚本就类似一个静态脚本了,而且这个游戏对象也永远不会因为切换场景而被销毁。而且用起来非常方便。在需要调用它的地方直接调用就行了。
1 2 3 |
Global.instance.DoSomeThings(); |
- 本文固定链接: https://www.xuanyusong.com/archives/2938
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
十分感谢!
第二个方法既然脚本不挂,那么还需要创建game object干啥呢。直接使用一个普通的单例类不就可以了,一直在内存里面可以随便访问。创建game object的目的是什么呢?为了使用脚本的start, update等方法?
第二个方法,脚本确实有问题
唉 灵光一现,终于知道了为啥了,这个脚本是不需要挂的,调用的时候自动会实例化
我也遇到那个说GameObject go = new GameObject(“Globa”);这一行报错的问题了,求解决方法
具体错误说明和那位大力亲的一模一样
unity2017.1.0f3版本没有此问题
我们现在就是有一个Main场景,这个场景就是为了进行一些初始化的,这个场景初始化完成之后,会自动切换到下一个场景中去,但是其他任何的场景是无法切换到Main场景中来的
Main 就是你的初始化场景了
这个法子好
为此,我永远采用单场景模式了,不知道有没有缺点
有缺点, 就是LOADING动画不均匀了。。 而且要自己管理内存施放。。
第二个方法很好用,太巧妙了!
unity4.5不会出现该情况啊,在a场景中DontDestroyOnLoad(o),切换到b场景,只有一个o对象,再切回a场景出现两个o对象;再次切回b场景时,已经不会出现两个o了。我猜是unity修复了这个bug.虽然每次从其他场景切回a场景时,会出现两个o对象,这应该是可以理解的,毕竟从a场景中加载了一个原对象。
你测试的不对吧,我是4.5.0f6的,两个场景来回切换,还是会不断的加载出新的游戏物体来。
你好。我用了你的完全一样的代码测试,发现会在GameObject go = new GameObject(“Globa”);这一行报错。UnityException: You are not allowed to call this function when declaring a variable.不明白为什么。
错误是说你 在声明变量的时候 调用这个方法。。。 我没遇到这个错误呀。。
我想你也是没有碰到的,所以很奇怪
UnityException: You are not allowed to call this function when declaring a variable.Move it to the line after without a variable declaration.If you are using C# don’t use this function in the constructor or field initializers, Instead move initialization to the Awake or Start function.这是完整错误提示。
你是不是在类的声明变量时候就赋值了
没有,代码是完整复制过去的。开始是自己手敲代码,发现有问题,然后就完整复制代码过去。
怎么解决的。我也是这个问题!!!
函数里不要在声明变量的同时赋值。先在函数外声明,再在Start()中赋值。
start是在静态构造函数之后执行的,如果按你这样,就达不到作者所说的效果
我也是出现这种情况,请问解决了吗?