Search Unity

Character Movement by forces instead of directly modifying the PhysicsVelocity CD

Discussion in 'Physics for ECS' started by Opeth001, Nov 13, 2019.

  1. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Hello Everyone,

    i created a character movement system using the DOTS Physics, im using joysticks for direction + a Speed CD then affect the result to the PhysicsVelocity CD.

    im looking for a way to move the player by forces instead of directly modifying it's PhysicsVelocity, the reason is i need to send from Server to Clients the players velocity (for Sync Reasons) which normaly can be affected by the environmental obstacles but overrided by my movement system.

    Thank you!
     
  2. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    You do this with PhysicsWorld.ApplyLinearImpulse()

    However, "moving with forces" and "moving by directly setting velocity" are just two ways of doing the same thing. Applying an impulse/force just means adding to the velocity while taking mass into consideration. Like this:


    if you want to set velocity directly:
    • With velocity: physicsVelocity.Linear = targetVel
    • With impulse: PhysicsWorld.ApplyLinearImpulse((targetVel - physicsVelocity.Linear) / invMass)
    If you want to add velocity:
    • With velocity: physicsVelocity.Linear += addedVel
    • With impulse: PhysicsWorld.ApplyLinearImpulse(addedVel / invMass)
    If you want to apply acceleration:
    • With velocity: physicsVelocity.Linear += acceleration * deltaTime
    • With impulse: PhysicsWorld.ApplyLinearImpulse((acceleration / invMass) * deltaTime)
    If you want to add impulse:
    • With velocity: physicsVelocity.Linear += (addedImpulse * invMass)
    • With impulse: PhysicsWorld.ApplyLinearImpulse(addedImpulse)
    If you want to apply force:
    • With velocity: physicsVelocity.Linear += (force * invMass) * deltaTime
    • With impulse: PhysicsWorld.ApplyLinearImpulse(force * deltaTime)

    Impulse and Force take into account the body's mass. Velocity and Acceleration don't.
    Impulse and Velocity are an instant change. Force and Acceleration are over time.

    When it comes to character controllers, I often prefer working with velocity directly because to me that's the most clear and fail-proof way to do it. Adding forces/impulse will always take mass into consideration, but with a character you often have a target velocity that you want to be able to reach regardless of your mass.

    - Explosions would do a one-time impulse add
    - Wind would apply a force every frame
    - Character jump could be a one-time velocity add
    - Gravity would apply an acceleration every frame (doesn't care about mass)
    - Character movement could apply an acceleration (or other formulas such as interpolation, etc...)

    And all of these are compatible for working with eachother. If your character gets pushed by an explosion impulse, that impulse modifies the velocity that your character movement acceleration will affect afterwards.

    (I also haven't tested that code but that's the general idea)
     
    Last edited: Nov 14, 2019
  3. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    Thank you that’s really helpful!!
     
  4. Plnda

    Plnda

    Joined:
    Nov 23, 2016
    Posts:
    14
    Last edited: Nov 30, 2019
  5. Filtiarn_

    Filtiarn_

    Joined:
    Jan 24, 2013
    Posts:
    173
    I know this is kinda old but I got a question similar to this. How would I apply velocity at a point of the object?
    Rigidbody has a function for it.
    Code (CSharp):
    1.  body.AddForceAtPosition(direction.normalized, transform.position);
     
  6. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    This is much trickier because a force at a point will probably induce an angular vel as well. This can be calculated, but in that case you're better off just going with PhysicsWorld.AddImpulseAtPoint

    (Can't remember if that really was the name of the function but it's somewhere in PhysicsWorld)
     
    Filtiarn_ likes this.
  7. Filtiarn_

    Filtiarn_

    Joined:
    Jan 24, 2013
    Posts:
    173
    Thanks
     
  8. PragneshRathod

    PragneshRathod

    Joined:
    Feb 7, 2018
    Posts:
    7
  9. Sab_Rango

    Sab_Rango

    Joined:
    Aug 30, 2019
    Posts:
    121
    Code (CSharp):
    1.  
    2. ApplyImpulse(PhysicsWorld, Int32, float3, float3)
    3.  
    4.  
    5. Declaration
    6. ///////
    7. public static void ApplyImpulse(this PhysicsWorld world, int rigidBodyIndex, float3 linearImpulse, float3 point)
    8. //////
    9.  
    10. Parameters
    11. Type    Name    Description
    12. 1...PhysicsWorld    world  
    13. 2....System.Int32    rigidBodyIndex  
    14. 3...float3    linearImpulse  
    15. 4...float3    point  
    16.  

    link https://docs.unity3d.com/Packages/c...hysics.Extensions.PhysicsWorldExtensions.html


    Edit:
    I found that this code is not exists, then I found real used code here in Boat attack sample
    https://github.com/Verasl/BoatAttac...ics Items/Systems/ApplyBuoyancyForceSystem.cs

    but this applyimpulse() is not locally point and force direction.. Both of them are global point position and force direction


    Hopefully there is some realistic impulse done here in mousepick script in physics sample
    https://github.com/Unity-Technologi...ommon/Scripts/MousePick/MousePickBehaviour.cs
     
    Last edited: Oct 16, 2020
    jconsole likes this.