一、在解决这个问题前需要先看一下MonoBehaviour的生命周期(注意一下FixedUpdate和Update的顺序):
二、原因分析
移动物体加刚体后,在Update中碰撞体跟着物体进行了移动,那么这一次的生命周期循环里,Update之后没有物理判断了。这一帧的画面渲染出来的时候,物体碰撞体是嵌入了墙体。而在下一帧的FixedUpdate进行了物理判断,发现碰撞体是嵌入的。那么按照物理规则,物理引擎把物体给弹出来保证物理正确。这样也就导致我们看到物体发生碰撞时抖动。
三、解决方法
方法一:
FixedUpdate是固定帧,每一帧的时间相同,FixedUpdate控制移动逻辑(LateUpdate控制相机跟随),如下:
bool move = false;
void Update()
{
if (!move) return;
float speed = 10f;//移动速度
transform.position += transform.forward * speed * Time.deltaTime;
}
方法二:
如果一定要在Update方法里处理移动,那么可以按下面这样处理:
bool move = false;
void Update()
{
if (!move) return;
float speed = 10f;//移动速度
float radius = 0.58f;//物体碰撞半径
Vector3 from = transform.position;
Vector3 interpolation = transform.forward * radius;
Vector3 dis = transform.forward * speed * Time.deltaTime;
Vector3 to = from + interpolation + dis;
//Debug.DrawLine(from, to, Color.red);
RaycastHit rh;
if (Physics.Linecast(from, to, out rh, LayerMask.GetMask("Terrain")))
{
dis = rh.point - from - interpolation;
}
transform.position += dis;
}
方法三:
使用CharacterController控件,使用方法可以看一下CharacterController