您的位置:首页 > 移动开发 > Unity3D

unity coc 战斗回放总结

2015-10-05 16:20 274 查看
直奔主题,战斗回放的两种方式:

1.记录每一帧的状态,包括所有的对象的位置,动作等。优点是通用,易于实现。缺点是不易扩展,如果你增加某种状态,就要在回放中增加对应的实现代码。而且文件很大,假设你记录2分钟,120s,那么就是6000帧以上,每一帧假设100个对象需要记录,那么这个数值压缩后基本在M级别以上,你打一场战斗要上M的数据量,对于移动端流量是不可接受的。

2.记录起始状态和玩家全部操作。优点是存储的数据量很小,war3就是这么做的,一场20分钟比赛,replay还不到1M。缺点是对编码限制比较多,特别是对Unity这种根据cpu调整帧率的引擎。后面细说。还有一个缺点就是不能够跳到某一帧播放,因为它必须经过计算才能得出那一个时刻的结果。

那么如果我们要开发一款用Unity引擎的coc游戏的战斗回放,这虽然是作死,我一直以为不会有人这么做。但我还是太年轻,Unity5的demo里面,展示了一个英国公司开发的coc游戏,我下载过来后,发现它是有战斗回放的,而且完美还原,没有丝毫的差别。我迫不及待的破解了它的代码,用了三天时间看了他replay的相关代码。在这里和大家分享下它的做法:

1.首先所有战斗逻辑都必须在FixedUpdate中实现。但是这样会带来很多问题,我们都知道Update里面移动物体,利用dealtTime会得到平滑的移动,但是FixedUpdate做不到,因为它可能一帧调用多次,甚至压根不调用,解决方案是数据逻辑放在FixedUpdate中,而移动更新逻辑放在Update中,详细如下:不能使用unity自带的寻路系统,因为那是基于Update的,建议使用A*寻路,FixedUpdate负责计算路径,Update负责更新位置。但注意,所有战斗逻辑相关的位置必须取得FixedUpdate中的位置,而不能获取GameObject的position,因为不同帧率GameObject位置不同,但FixedUpdate中的计算结果一定是一样的。

2.这一点我不是很确定,但它是这么做的。FixedUpdate之间的顺序是否得到保障,就是说假设你有A B,两个FixedUpdate是否永远是A先B后呢?我也不知道,但有一种方法可以保障,就是你自己调用A.FixedUpdate 再调用B.FixedUpdate, 它将所有的组件全部放到一个list中,永远按照这个list执行FixedUpdate,保障顺序的一致性。

3.禁止战斗相关的yield return,同理,invoke也不可以使用,因为他们都是基于Update的。

4.Animator中的事件,暂时我没有验证,不过它全部使用了时间代替事件编辑触发。

5.玩家的输入都要延迟一帧,就是说你的状态更新要到下一个FiexUpdate中更新,不能马上更新,不然可能会导致执行顺序的不一致。

最后再提一下录像加速的原理,war3这种的加速并不是跳帧,而是加快计算速度,比如本来FixedUpdate是0.1s,那么2倍速就是0.05s,当然画面更新也要对应加倍。那你不是说,如果加速100倍,电脑性能跟不上怎么办,哈哈,所以war3只能加速4倍吧。

可能有所遗漏,不过总体思路基本清晰,感觉限制这么多,对编程要求也提高不少,不得不感慨war3的设计,那个年代设备性能不好,所以war3用了很多让人惊叹的技术,这个replay技术放到现在我也觉得非常棒。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: