Character Movement by forces instead of directly modifying the PhysicsVelocity CD

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!

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)

14 Likes

Thank you that’s really helpful!!

How would you do

AddRelativeForce(appliedLinearForce, ForceMode.Force);
AddRelativeTorque(appliedAngularForce, ForceMode.Force);

With the new Unity Physics?

Im trying to mimic this behaviour: GitHub - brihernandez/ArcadeSpaceFlightExample: Simple example of arcade style space sim flight physics.

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.

 body.AddForceAtPosition(direction.normalized, transform.position);

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)

1 Like

Thanks

@PhilSA have good Explanation
But i have made Extra Script that Will Apply Acceleration Force on rigidbody in Dots physics.
take Look in GitHub Repository

ApplyImpulse(PhysicsWorld, Int32, float3, float3)


Declaration
///////
public static void ApplyImpulse(this PhysicsWorld world, int rigidBodyIndex, float3 linearImpulse, float3 point)
//////

Parameters
Type    Name    Description
1...PhysicsWorld    world  
2....System.Int32    rigidBodyIndex  
3...float3    linearImpulse  
4...float3    point

link Class PhysicsWorldExtensions | Unity Physics | 0.5.1-preview.2

Edit:
I found that this code is not exists, then I found real used code here in Boat attack sample

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-Technologies/EntityComponentSystemSamples/blob/master/UnityPhysicsSamples/Assets/Common/Scripts/MousePick/MousePickBehaviour.cs

1 Like