《反转重力》 项目总结
文章目录
- 起因
- 跷跷板功能——和定点数系统
- OnCollisionEnter和射线检测
- 回放系统和bug
- 2d物理材质的问题
- 用预制体制作预制体
- 砸穿地面
- TextMesh来替代世界UI
- 好的优化手感
- 间接碰撞检测的思路
起因
- 前段时间做了一个益智解谜游戏。
- 我的游戏
- 大家可以支持一波
- 完全是我一个人独立制作完成的,期间遇到了一些问题。在这里记录下来。
- 当然有些问题是到现在也没有解决。
跷跷板功能——和定点数系统
- 我想做一个能量转换装置,类似跷跷板,就是左边物体掉下来,可以把右边东西弹上去
- 我用的是动能守恒定理,在左边碰到弹簧的时候,记录他掉落的高度,然后用
mgh = 1/2mv^2
- 计算出右边物体的速度,把这个速度赋值给刚体就好了。
- 但真正运行的时候,因为浮点数的各种原因,导致数据会有误差,即使是完全质量相同的物体A和B
- A掉落,B上升,也达不到和A完全相同的高度。
- 在查阅一番资料后,得知即使是unity的物理系统,使用的也是浮点数系统。
- 可是我也不会定点数啥的。只好凑合着用,当作能量损耗的特性。
OnCollisionEnter和射线检测
- 角色跳跃需要记录地面
- 我记得很久以前写这个功能的时候用的是回调函数
OnCollisionEnter
- 可是实际运行中有很多问题。
- 最典型的问题是,
角色
只要触碰到碰撞体
就会触发这个函数,但我需要的是A在碰撞体之上的时候
才可以跳跃。 - 当然我可以加上高度检测啥的
Role.y-collision.y>0
这样的触发条件,可是这个y值
应该取Role
的中心点吗,如果角色本身就比平台高一些呢? - 所以要在
Role
的底部加一个检测点作为y值
,同时要在被检测物体的顶部加一个检测点作为y值
- 这样就很麻烦,用射线的方式就很好。
- 另外还有个问题,就是
OnCollisionEnter和OnCollisionExit物体碰撞发生进入和进出总是会出现各种各样奇怪的问题
- 但是射线检测也有问题
最起码的你要在角色的底部均匀安插好几个检测点,保证在特殊情况下也可以检测到地面
回放系统和bug
- 当时写回放系统利用的是
fixUpdate
- 因为
fixUpdate
每隔0.05s
就更新一次,所以更新的频率也是固定的。 - 我就在
fixUpdate
里面记录玩家的操作就行了,然后再在fixUpdate
里面进行回放。 - 可问题是
玩家的输入是按照每一帧来更新的
,所以倒霉的是,如果一帧的渲染时间过长,比如1s才更新那么fixUpdate在这一帧就会执行多次,频繁收到输入事件,只要玩家在这一帧里面按下了某个键,那么fixUpdatej检测到的就一直是true
- 另外还有不知名的bug导致我的系统失败了,我也不想检查为什么了。
- 查到最后我觉得还是定点数这些的问题,因为
我利用fixUpdate记录的不是每一次各个单位的位置情况,而是玩家的操作即发送的指令,类似于,0s开始游戏,1s后玩家开始发射一个炮弹,3s后又做了什么.......
- 但是
fixUpdate
的更新时间并不是固定的,虽然名义上说是按照固定时间间隔来更新,可是我实际测试了一下,会有0.1的差距,有时候是0.02,有时候是0.19
- 就很一言难尽啊。因为我这是
模拟玩家操作来回放的,即相同时间+相同输入+相同环境 = 同样的输出
- 如果有
0.01s
的差距,玩家可能已经走了一段距离了,回放的就不是预定的操作。 - 只好暂时放弃。目前没有研究过定点数系统。
2d物理材质的问题
- 在修改完
物理材质的一些属性后要过个几秒才会显现出效果
如果是没有材质的物体A和有材质的物体B,就按照有材质的B的参数进行计算,B和A会产生摩擦力
如果是两个都有材质,那么就按照最小值来计算,A材质的摩擦力是0,B材质的摩擦力是0.8,那么B就会滑过A
用预制体制作预制体
- 我要制作关卡,关卡由几个组件来构成,即
角色,风扇,弹簧这些
- 我先
制作组件的预制体
,然后用预制体来拼接成关卡预制体
这样当我修改组件预制体的时候,关卡预制体里面的组件也会跟着发生改变
- 但是!
注意关卡里面的组件如果变成了白色,即和预制体切断了关联!这时候这些关卡里面的组件就变成了漏网之鱼
砸穿地面
- 这个问题在于,我用三个方块,一个方块很重,切下降速度很快,如果落到下面两个方块身上,就会把方块砸到地板里面。
- 可是地板已经被我设置成静态物体了。
- 在网上找了一些网友咨询了一下,原因在于,
方块的运动速度过大,所以在物理引擎固定间隔的时间内进行运动,超过了地板,这时候引擎再去检查就来不及了
- 所以可以把
fixTime变小一点,但这样导致的后果就是游戏帧数不足,我的fixUpdate函数里面也有很多需要更新的函数,就导致他们一帧要运算几百次,这样导致的后果是灾难性的,但我这只是个小游戏,所以,随便啦~
TextMesh来替代世界UI
- 我需要一些UI跟随在玩家头顶,
好像很传统的形式有两种,第一是实时计算玩家的位置,转换成屏幕坐标后将赋值给UI
- 第二是
直接把UI作为摄像机渲染,挂到角色身上完事,简单省力
- 第三就是
把3DText作为UI放置到角色身上
3DText的问题是显示的会很模糊,在网上查到的资料是把字体变小,把整个文本变大。确实有用
好的优化手感
- 在网上看到了
威力狼跳
,就是玩家离开地面一段时间一般是0.2s
后依旧可以让玩家进行跳跃 - 在实践中加上这个功能后,真的好了很多。
- 另外,一直觉得Unity自身的物理碰撞体这些很烂,最近看到一个手撸碰撞体的,有时间研究一下。
间接碰撞检测的思路
- 比如需要检测方块是否和玩家碰撞,即使是间接接触。
A和玩家接触了,B接触了A,那么B也算是和玩家接触
- 存放一个值来保存是不行的。
这种思路是,比如A和玩家碰撞了,所以存一个flag记录为true,然后B检测到了A为true,所以把自己也设置为true,
可问题是,如果A离开了玩家,这时候A依旧会检测,然后发现B是true,然后把自己也设置为true,可他实际上已经不再和player碰撞了
- 最简单的方式是用射线
B向左发射射线,撞到了A,继续让A发射向左发射,一直到再也检测不到物体为止。这样递归遍历就可以知道自己到底有没有间接接触玩家了
发布评论