Unity 获取碰撞前一刻的速度

在获取碰撞对象的初速度时,如果直接调用OnCollisionEnter(Collision collision) 中的collision.collider.velocity, 所获取的速度其实是碰撞对象在碰撞发生后的速度,一个典型的现象就是假如在发生碰撞前如果碰撞对象的速度为0,但在碰撞判断时所获得的速度却不为0, 而是碰撞发生瞬间后,物理引擎后一帧的速度!这将对碰撞判断造成非常严重的影响。

Unity 似乎没有在文档中明确说明这一点,但我觉得这很可能和Unity的周期循环顺序有关,如图,物理的碰撞Internal Physics update似乎发生在OnCollisionEnter接口之前,导致通过OnCollisionEnter获取的物体速度晚于实际碰撞发生时刻!

Script Lifecycle Flowchart. The following diagram summarises the ordering and repetition of event functions during a script’s lifetime.

在经过反复的尝试后我找到一个解决方案,即在每一个可能会要计算碰撞伤害的物体上附加一段代码,这段代码将有一个public的变量记录着物体的实时速度,将代码放置在Update循环中,由于Update晚于OnCollisionEnter(),这样可以确保物体在被碰撞之后该数据才会被刷新覆盖,这样就能一直记录着物体上一个周期循环的速度, 放在FixedUpdate循环中同样也可以,FixedUpdate发生的最早,所以初始速度可在发生碰撞之前就准备好了。这样在碰撞时获取该数据,两种方法都能获得物体碰撞前一刻的速度了:

要判断碰撞物体的部分脚本:

[SerializeField] Rigidbody rb; // player
public Vector3 Player_Velocity;
  void Awake()
    {
        rb = GetComponent<Rigidbody>();
       
    }

void FixedUpdate()//or Update()
    {
        Player_Velocity = rb.velocity;
//since the collision will get the late velocity that gives wrong damage, so we need to get the velocity in fixed update (earlier)
         }	

碰撞检测和判断,放在其它物体脚本中:

   void OnCollisionEnter(Collision collision)
    {
        if (rb.velocity.magnitude < other_Player_Velocity.magnitude)
        { 
            //这样就能够获取碰撞前另一个物体的初速度(other_Player_Velocity)了              
            //Do something
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_46146935/article/details/124464587
今日推荐