Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Solved] [Unity Physics] Help needed to understand the correct way to use ApplyImpulse

Discussion in 'Entity Component System' started by RBogdy, Jun 5, 2019.

  1. RBogdy

    RBogdy

    Joined:
    Mar 6, 2019
    Posts:
    65
    Hello,

    As I'm learning the new ECS ways, I thought it would be fun to replicate a bowling game. Unfortunately I ran into problems when using the Unity Physics ApplyImpulse() function; the ball just 'jumps' from the floor instead of launching forward and I can't tell why.

    From the beginning:

    I made some sort of slingshot mechanism using the 'MousePickBehaviour' script as an example, so I ended up with 2 systems:

    1. Begging of the shot - updates a component native array copy with a start position (from a mouse click), does a ray cast job to get the entity touched at the start position and calculates the point in world, body from world and point on body (pretty much copy/paste from 'MousePicker')
    2. End of the shot - updates a component native array copy with the end position (from a mouse release) and the difference between start and final points

    A 3rd system is used to apply the impulse on the ball and this one was inspired by the PhysicsExamples Demo number 5 - Apply Impulse case
    So this 3rd system receives references to the above mentioned systems and replicates the same behaviour as 'LinearDashpotBehaviour' script and at the end applies an impulse.

    The problem is that the ball 'jumps' and is not sliding on the 'floor'.

    Force calculus:
    Code (CSharp):
    1. var deltaX = EndPosition.x - StartPosition.x;
    2. var deltaZ = EndPosition.z - StartPosition.z;
    3. var strenght = sqrt(deltaX * deltaX + deltaZ * deltaZ);
    4. var direction = mouseStartPosition - mouseEndPosition;
    5. var force = 5.0f * strenght  * (direction / sqrt(lengthsq(direction)));
    6.  
    Relevant calculus in system no 3:
    Code (CSharp):
    1.  
    2. int rigidBodyIndex = world.GetRigidBodyIndex(StartSystem.ShotStartDatas[0].Entity);
    3. RigidBody rb = rigidBodyIndex >= 0 ? world.Bodies[rigidBodyIndex] : RigidBody.Zero;
    4. var pos = math.transform(rb.WorldFromBody, StartSystem.ShotStartDatas[0].PointOnBody);
    5. var linearV = world.GetLinearVelocity(rigidBodyIndex);
    6. var impulse = EndSystem.ShotEndDatas[0].Force + 0.5f * linearV;
    7. world.ApplyImpulse(rigidBodyIndex, impulse, pos);
    8.  
    PS: When I change the world.ApplyImpulse to world.SetLinearVelocity I get the behaviour I want (the ball slides) however there's no angular movement (as expected in linear velocity)

    Please help me understand the correct way of using ApplyImpulse for my needs.
     
    Last edited: Jun 5, 2019
  2. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    502
    var direction = mouseStartPosition - mouseEndPosition;

    If this comes from raw mouse data, then this will x/y floats right?
    It feeds into 'force' without any axis changes.

    var impulse = EndSystem.ShotEndDatas[0].Force + 0.5f * linearV;

    It would jump if the mouse moved in y position.

    Perhaps you want to take the mouse/force y and use it as a 'z' impulse?
    Not sure if my assumptions about the rest of your code are accurate, and I have no comment or assumptions on the behaviour of 'world.ApplyImpulse'.
     
  3. RBogdy

    RBogdy

    Joined:
    Mar 6, 2019
    Posts:
    65
    I'm doing the 'Camera.main.ScreenToWorldPoint(new float3(mousePosition.x, mousePosition.y, Camera.main.transform.position.y))' conversion before sending it to the component copy array for both the initial and final position.

    I did a debug Log for the Force before sending it to ApplyForce and I get values such as:
    float3(-11.10921f, 0f, 35.31141f),
    float3(-17.19282f, 0f, 17.06057f), etc.

    So there is no Y value when the force is sent to ApplyForce, however my 'Object' jumps from the floor. Any ideas why that might happen?

    As I said before, world.SetLinearVelocity sends the 'Object' gliding as it's supposed to, with no Y movement.
     
  4. RBogdy

    RBogdy

    Joined:
    Mar 6, 2019
    Posts:
    65
    The root cause of the problem was the point at which I chose to Apply the impulse. After some maths and thinking I got it to work properly.
     
    Shinyclef likes this.
  5. yifanchu183

    yifanchu183

    Joined:
    Jul 4, 2019
    Posts:
    41
    I use applyImpulse with y is 0,but entity jump, how to solve it