unity3d 切换场景不销毁对象池中的物体方案

来源:互联网 发布:返利网 淘宝taosave 编辑:程序博客网 时间:2024/05/11 20:12

         要在手机上玩转u3d,一定会做的一个就是对象池,在这里我不打算讨论对象池本身,基本思路大同小异。我这里想讨论的是切换场景引发的对象池中对象的问题。

        首先如果你什么都不处理,那么一旦你切换场景,你会发现你对象池中所有GameObject本身或者变量全部都变成了null。你下次使用这个对象就会抛出指针异常,所以你肯定会去研究怎么切场景不销毁,ok,你马上就能找到DontDestroyOnLoad方法,只要声明之后,这个物体就不会被销毁。

       然后你发现有那么多对象都需要声明,会很麻烦,所以你可以新建一个物体,挂上不销毁的脚本,然后把不需要销毁的物体全部放到它里面,那么所有的物体切换场景就不会销毁了。

      然后这样做的第一个问题,就是重复加载同样的场景,你会发现这个不销毁的新建的总物体每次都多复制了一个。因为上一次的保存下来,而这一次的还在,这个也不难解决,你可以直接判断场景中是否已经有这个物体,如果有就添加,没有就不用添加了,当然你可以参考雨凇MOMO的做法:http://www.xuanyusong.com/archives/2938(他说他的做法更好。。。虽然我觉得没有他说的那么夸张)

     接下来似乎不会有什么问题,但其实如果你真的在项目中这么做,你会发现还有很大的两个问题。

     1.我们放对象的时候,经常会把对象设置成不同层,比如默认是default, 可能会有UI层,  effect层。ok,当你把不同层的东西都放在一个obj下面的时候,下次再次加载场景时,它的父亲突然就变了。莫名其妙的把这个非销毁的所有物体挂在了UI层下(这是我碰到的情况,也许可能会挂在别的层,总之就是父亲变了)。这样问题就大了,因为如果父亲不是销毁的,那么儿子标记销毁是无效的,而且改变父亲这种行为也不是我们想看到的。也许你觉得只要重新设置一下父亲就好了。。。但所有儿子的Layer也会全被改掉。。。。你得全部重新设置,蛋碎。。。所以不建议这么做。 要解决也不难,只要注意不同层都应该要有自己的一个非销毁obj,比如default有一个,UI也要有一个,这样就不会乱了。

     2.第二个问题才是大问题。切换场景后,现在出现了三种情况,直接被销毁的物体,包括大部分脚本和GameObject. 不被销毁的静态变量和全局数据。  最后就是挂了不销毁脚本的一堆GameObject.让我们一种一种看。

     第一种是最简单的,既然被销毁了,那么下次重新构造一个就好了,也是问题最少的做法,当然性能最差。

     第二种最常见的就是事件,你给物体挂上了事件一般都是存在一个事件管理器里的,当然正常的做法肯定是在销毁流程的时候会把所有的事件移除,但是切换场景可能是中途退出,所以不一定会把流程走完,所以建议在OnDestroy函数中处理这些问题。因为不论是否走正常流程,被销毁的物体肯定会进入OnDestroy函数,你只要在里面移除事件即可。

    第三种最复杂,首先由于你已经标记为不销毁GameObject,所以你必须在场景切换前自己把所有的物体打回对象池。你可以用代理或者消息实现。这里要注意如果物体已经在对象池中,务必将所有的事件先移除,不然会重复调用。最后将物体移入对象池后,仍然需要注意下次取出的时候,有些东西可能已经不是正常的了。特别是你是对象池中的物体,而你的有些变量是被销毁的物体的引用,这个就需要你自己写逻辑维护了。

    总之对象池虽好,但碰到这种蛋疼问题还是要早发现早处理。

0 0
原创粉丝点击