# Character Movement by forces instead of directly modifying the PhysicsVelocity CD

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

1. ### Opeth001

Joined:
Jan 28, 2017
Posts:
1,112
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

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)
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

Joined:
Jan 28, 2017
Posts:
1,112

4. ### Plnda

Joined:
Nov 23, 2016
Posts:
14
Last edited: Nov 30, 2019
5. ### 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):

6. ### 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.

Joined:
Jan 24, 2013
Posts:
173
Thanks

Joined:
Feb 7, 2018
Posts:
7
9. ### 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.

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.