Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Feature Request Relative velocity of a collision factoring in angular velocity.

Discussion in 'Physics' started by Camobiwon, Sep 20, 2023.

  1. Camobiwon

    Camobiwon

    Joined:
    Dec 7, 2021
    Posts:
    6
    Hi there!
    I've looked around a while for this, found that there was no solution in-Unity for this, and resorted to making my own implementation of it, but I would want to perhaps know the reason for lack of this.
    In OnCollisionEnter, collision.relativeVelocity only returns the linear velocity of 2 rigidbodies, not factoring in the angular velocity at all. In a hypothetical example, having a spinning object hit a still object would result in 0 relative velocity as neither were linearly moving.
    collision.impulse also results in strange behavior sometimes that is not acceptable for my usage, I've gotten instances of times where relativeVelocity reported as ~18 while impulse was 0.
    I don't expect relativeVelocity to factor in angular velocity as that would obviously result in a lot of previous projects breaking, but is there some kind of chance we could get some implementation of this with angular velocity factored in? Perhaps something along the lines of collision.pointVelocity.
    For reference, this is how I implemented it for my stuff, disregarding the collision handling and just storing the last tick's velocity.

    Code (CSharp):
    1. Vector3 thisRBVel = lastTickState.velocity + Vector3.Cross(lastTickState.angularVelocity, point - lastTickState.position - Rigidbody.centerOfMass);
    2. Vector3 otherRBVel = Vector3.zero;
    3. if(otherBody != null) {
    4.     otherRBVel = otherBody.lastTickState.velocity + Vector3.Cross(otherBody.lastTickState.angularVelocity, point - otherBody.lastTickState.position - otherBody.Rigidbody.centerOfMass);
    5. }
    6.  
    7. return otherRBVel - thisRBVel;
    Maybe I totally missed some way to get this info, but this seems like it would be extremely useful for people to have in the collision report from OnCollisionEnter or Stay!

    If anyone has any other solutions that the one I wrote, or perhaps if some Unity employee could chime in to give some insight, that'd be great :)
     
    Edy and ElectricDragon like this.
  2. ElectricDragon

    ElectricDragon

    Joined:
    Mar 1, 2016
    Posts:
    1
  3. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,477
    Most likely that's how it's exposed in PhysX. Unity just exposes the values given by the physics engine.

    EDIT: Note that you may use Rigidbody.GetPointVelocity() to get the velocities of the contact point in both rigidbodies, which may greatly simplify your code.
    Code (CSharp):
    1. Vector3 thisRBVel = thisRigidbody.GetPointVelocity(point);
    2. Vector3 otherRBVel = otherRigidbody != null? otherRigidbody.GetPointVelocity(point) : Vector3.zero;
    3. return otherRBVel - thisRBVel;
     
  4. Camobiwon

    Camobiwon

    Joined:
    Dec 7, 2021
    Posts:
    6
    This was the initial idea, sadly this is all being processed in OnCollisionEnter, post-physics simulate and where velocities are now affected. I store the last tick velocity to get a delta from current velocity so in case it hit something and came to a stop, I now know how much the velocity has changed. So unfortunately GetPointVelocity doesn't work for that case.