测试环境很简单,一面墙,红色方块不停向前
然后,由于刚体是FixedUpdate执行的,把FixedUpdate执行间隔调慢一些方便Debug:
OK,下面还原一次经典的穿透问题:
测试脚本:
void Update()
{
transform.Translate(, , * Time.deltaTime);
}
OK,然后我测试了几种方法,最后发现直接改速率最为有效,AddForceAtPosition虽然也可以但是不常用:(注释掉的方法都测试失败,碰撞检测"连续/非连续"都测过)
void FixedUpdate()
{
//transform.Translate(0, 0, 10 * Time.deltaTime);
//transform.Translate(0, 0, 10 * Time.fixedDeltaTime);
//GetComponent<Rigidbody>().position += transform.forward;
//GetComponent<Rigidbody>().MovePosition(transform.position + transform.forward * 10 * Time.deltaTime);
//GetComponent<Rigidbody>().MovePosition(transform.position + transform.forward);
GetComponent<Rigidbody>().AddForceAtPosition(new Vector3(, , ), transform.position + transform.forward, ForceMode.VelocityChange);
GetComponent<Rigidbody>().velocity = transform.forward * 100000f;
}
但这只是防止FixedUpdate更新频率低的解决方法,我极限测试了一下,又穿透了:
void FixedUpdate()
{
GetComponent<Rigidbody>().velocity = transform.forward * 100000f;
}
然后我尝试把碰撞检测改为连续:
终于,没有出现穿透:
再补上一个夹角测试:(卡是因为我把FixedUpdate频率调低了)
测试脚本:
void Update()
{
if(Input.GetKey( KeyCode.A))
{
GetComponent<Rigidbody>().velocity = transform.right * -20f;
} if (Input.GetKey(KeyCode.D))
{
GetComponent<Rigidbody>().velocity = transform.right * 20f;
} if (Input.GetKey(KeyCode.W))
{
GetComponent<Rigidbody>().velocity = transform.forward * 20f;
} if (Input.GetKey(KeyCode.S))
{
GetComponent<Rigidbody>().velocity = transform.forward * -20f;
}
}
另外测了一下Animator的穿透情况,打开根运动造成的位移不会穿透。如果是动画控制的位移会穿透,但除非你强制移除Animator,动画位移不会有什么影响
并且和UpdateMode的具体模式无关