Search Unity

Altering ball bounce direction from the point of contact

Discussion in 'Physics' started by FissicsPeep, Oct 5, 2018.

  1. FissicsPeep

    FissicsPeep

    Joined:
    Jan 14, 2014
    Posts:
    79
    Hi,

    I'd like to know if it's possible, using PhysX and what Unity expose of it, to be able to modify the bounce direction of a fast moving ball hitting a surface. But it's important that the direction change is made from the point of contact, as that will alter the final position of the ball - imagine the arrows in this image are the balls entire movement within 1 physics update for example.



    Is this possible? How could I go about doing this?

    Thanks!
     
  2. FissicsPeep

    FissicsPeep

    Joined:
    Jan 14, 2014
    Posts:
    79
    Digging into this a bit more and it seems that you can't get a callback at the time of the actual collision to be able to modify the normal used for the collision (I found a request ticket for that feature to be added).

    So how would you do this for a golf game for example then? Imagine a fast moving golf ball that hits some of the rough surface, you would want it to bounce off in random directions like it's hitting small sticks and leaves on the ground?
     
  3. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,408
    could add some random force on collisions?
     
  4. FissicsPeep

    FissicsPeep

    Joined:
    Jan 14, 2014
    Posts:
    79
    But that's kind of the problem. Adding the force then, would be after the bounce, and the ball would already be a distance from the surface at that point. So the ball would bounce up, and then a force applied and it would appear to change direction in the air.
     
  5. xorpheous

    xorpheous

    Joined:
    Mar 28, 2018
    Posts:
    19
    Think of the problem with the velocity resolved into components parallel and perpendicular to the surface normal. In a perfectly elastic collision, the component perpendicular to the normal (parallel to the face) will be unaffected and the component parallel to the normal (perpendicular to the face) will be flipped. (v_after = - v_before). In an inelastic collision without friction, only the perpendicular component is affected and the velocity after the reflection is reduced by some factor, the coefficient of restitution. (v_after = - coeff * v_before). With an axially aligned surface, this is simple, but for an arbitrarily oriented surface, you need to project the initial velocity onto the surface normal. After a bit of vector algebra, you can arrive at the following:

    vf=vi−(ε+1)(vi⋅n)n

    where vf is the velocity vector after the reflection, vi is the velocity before the collision, n is the surface normal (note, this is a unit vector), and ε is the coefficient of restitution. If ε=1, the collision is perfectly elastic and the angle of reflection is exactly the same as the angle of incidence. If ε < 1, the collision results in a loss of energy and the angle of reflection is greater than the angle of incidence until at ε=0, the object just slides along the surface. If ε > 1, energy is added to the object and the angle of reflection is less than the angle of incidence. This last case is similar to what happens with a jet bumper in a pinball game.

    Code (CSharp):
    1.         Vector3 vf = Velocity - ((Erest + 1) * Vector3.Dot(Velocity, Cube.transform.up.normalized)) * Cube.transform.up.normalized;
    By randomizing your coefficient (Erest in the above line of code), you can randomize the reflection angle.