这两周在开发的弹幕引擎遇到了一些性能问题:
1.同一时刻创建大量子弹会造成卡屏,跑起来就是一顿一顿的,原因是new一个对象很耗CPU。
2.draw call 和 batch 的问题。
第一个问题可以使用OT自带的对象池功能解决:
1)初始化对象池 PreFabricate(string objectPrototype, int numberOfInstances)
objectPrototype 对象必须放在OT prefab的子对象Prototypes下。
2)要销毁对象时,必须调用 OT.DestroyObject(xxx),不然对象无法回收到pool中。
3)当要创建新的对象时调用OT.CreateObject(objectPrototype ) ,刚好对象池里有可以使用的闲置对象时,OT就会自动服用该对象。但是要注意一个问题,被复用的对象已经被初始化过一次并运行过了,可能有一些参数必须重置,这个操作OT不可能帮你完成,因为OT不知道哪些参数需要重置。但OT在 CreateObject 方法内有一行代码:
g.SendMessage("StartUp",null,SendMessageOptions.DontRequireReceiver);
意味着OT在给你一个对象之前,让这个对象执行了这个StartUp函数,所以可以在对象的各个component里重写这个函数,必做必要的重置操作。
除了使用OT自带的对象池,还可以使用另外一个插件:PoolManager2,不过这个插件蛮贵的也不提供使用版,有米的就入手一个试试吧。
第二个问题是关于对象材质的问题。
我在一个弹幕demo中想让N个弹幕tween到一个颜色,通过改变OTSprite的tintcolor,结果发现帧率掉得很厉害:
1)弹幕刚生成的时候,Draw Calls只有3次,全部子弹都被batch到一起。
2)第二个操作是改变各个弹幕OTAnimatingSprite的帧图片,发现帧率等没有变化,性能瓶颈不是在切换动画帧上。
3)开始随机tween每一个子弹的tintcolor,发现DrawCall暴增,batched数剩0,帧率掉出翔来了。。
很显然,改变tintcolor会导致不能batch,每一个弹幕自己跑了一次渲染管线,超低效。
下一个操作是把所有子弹tween回同一个颜色,发现参数都恢复了,包括帧率。所以这个tintcolor的改变应该不是给每一个子弹生成了新的材质(Copy On Write写复制这种机制),只是同一次shader不能有不同的外部参数。
这个恢复机制反应出Unity和OT还是很智能的。
这个问题好像没有什么解决方法,最好的办法就是不要像我这样子搞=。=
做移动平台游戏,性能相当重要,这种华丽的效果还是放弃吧。
虽然做了对象池优化,但是帧率还是蛮低,以后加上游戏逻辑、碰撞检测、游戏场景、特效、GUI后,帧率又会降低,
所以性能革命这路子还长呀。