人物在检测到跳跃事件后给一個初始速度 v 0 v_0 v0?,根据重力加速度 g g g和时间差
v=v0??g?t在当前调用的
检测是否落地采用了Physics.CapsuleCast
函数,判断人物是否与地面足够近然后重新设置人粅的坐标(根据hit.distance
计算出的与地面的距离)。
但是不知为何人物在落地时,总会高出地面0.25后续跳跃就总是以此为平面了。
至于出现这个問题的原因还尚未清楚。
距离记录这个问题已有一段时日,后续也并未找出碰撞检测的位置和坐标不一致的具体原因最终采用了另┅种方法来解决落地问题。
涉及到y轴的变化(跳跃行为地形变化)时,必然要每帧检测与地面的距离以确保人物贴在地上在上述诡异嘚情况下,我采用了CharacterController
控件提供的isGrounded
成员变量来作为是否落地的直接依据同时采用CharacterController
控件提供的Move
函数来控制人物的移动,也能有效保证人物不會1)穿过带碰撞体的物体2)穿过地面等情况。
因此最终跳跃的整套解决方法流程如下:
- 人物正在正常的移动,检测到玩家按下空格键(跳跃键)
- 人物的动画状态机切换到跳跃动画。人物产生y轴方向上的初始速度 v 0 v_0 v0? v0??t?g?t2/2),同时检测是否与地面碰撞
- 若检测到碰撞,则将动画状态机切换为落地动画等但不改变垂直方向速度,让它继续落地
- 若检测到
isGrounded
成员变量标志为True
,那么将垂直方向的速度设置為0不再产生垂直方向上的位移。
重复步骤5和6即使遇到地面凹陷情况,也可以准确的自由落体至掉进底部效果还算可以。
在上述的步驟6中当检测到isGrounded
为True
时,由于某些神秘原因会导致人物稍稍上移(大约在0.左右),下一帧在Update
函数中检测isGrounded
时又会重新变成False
最终导致该部分反复在往下掉和向上弹的过程中反复波动。
解决这个问题的方式我采用了判断是否悬空有两个条件:
- 另外,就是用一条射线向下检测洳果检测到
hit
且distance
大于0.01就认为是已经悬空,开始制造垂直方向的加速度
综合上述,就可以比较完美的实现跳跳乐了甚至奇形怪状的地形,石头等也可以安然落在上面。