Problem with simulating air resistance

It’s been a long time since I posted here lol. Ok so anyways, I’ve been having a problem with air resistance simulation.

Air resistance happens because of an object colliding with the tiny air particles while moving. Air resistance formula also uses velocity in it.

Now what’s the problem? I run my simulation code on stepped calculating the bodyforces for air resistance and other custom forces. Well since the air resistance formula includes velocity, the velocity during stepped will not suffice because it can update in the physics frame.

Now what about heartbeat? Heartbeat fires after the physics simulation step this means this velocity will not suffice either, since it will be really outdated when the next physics simulation steps will take place.

So I need your guys help to figure out when I should apply air resistance.

I recommend checking out RunService’s new events that are made with these types of applications in mind

Im pretty sure these are just replacements for heartbeat and stepped as incapaz said here. So it wouldn’t cause in any difference in my code.

Bump still looking for help on this problem

I think you are having issues because legacy BodyMovers resolve before both Stepped and Heartbeat.

Don’t quote me on this, but you should try using the new physics objects, as they should evaluate during the Internal Physics Step, allowing changes during the Stepped event to be reflected in the simulation.

I’m using bodyforce is that considered as a new physics object?

Well, replication job sends is when properties are updated. That’s after stepped and heartbeat is fired, and the internal physics step is done.

So my Part.Velocity property used in the air resistance formula will be one frame behind. (Since the air resistance is calculated in the stepped frame).

Here’s an example of what i’m doing:

RunService.Stepped:Connect(function()
       local AirDrag = 1/2 * AirDensity * Part.Velocity^2 * DragCoefficent * SurfaceAreaInMovingDirection -- Part.Velocity is one frame behind because of the above
end

All BodyMovers are considered legacy. That includes BodyForce.

The replicated value will be one frame behind, but the simulation will adjust the position and velocity components of each part, so they should be up to date.

Alright.

I’m confused on what you mean in the second part.
A scenario where this is a problem is a collision. Part collides into the ground with immense velocity, so a lot of velocity is lost. However, high velocity from the previous frame is still used in the air resistance formula. Since, air resistance counters the object’s motion it will cause the part to move back up with some speed for a while.

This wont be a problem if the computer setting the force vector is also the network owner of the part. Physics is only calculated for each part the given computer has network ownership over. What remote clients will see is just the end result of the solved position and velocity every frame.

try run service.RenderStepped and delta time in it.
If you don’t want any bodymovers

Well that would still be delayed though.

Server set’s force-vector to: Vector3.new(0,-100,0) since 100 is the force of air resistance. Remember this 100 was calculated using the previous frame’s velocity so it’s delayed.

Let’s say that this frame the expected air resistance should be 50, as the velocity was lower this frame.

Ok so now client get’s sent the velocity: It’s the current velocity of the part + Vector3.new(0,-100,0) * Delta

However, what the simulation should actually have given if the air resistance was calculated correct is: current velocity of the part + Vector3.new(0,-50,0) * Delta

Assuming the part has server network ownership and assuming you are using LineForce instead of BodyForce:

In Stepped Event: Server sets force vector to Vector3.new(-100,100,100) on this frame.
Internal Physics Step: Physics engine applies force to rigidbody, changing velocity to (-50,0,0)
Replication Step: Part velocity is replicated as (-50,0,0)

Again, this should not be a problem.

I also believe you shouldn’t apply deltaTime to forces. The physics engine should handle that if I recall correctly.

This is what im talking about though, Vector3.new(-100,100,100) isn’t the actual air resistance force of the object, as it was calculated using the part’s previous frame’s velocity.

The current velocity could be something else, in turn replicating the wrong velocity to the client.

Ok, I was just being really dumb… I realized that the prevoios frame’s velocity could be used, if the velocity of the part remained the same before the VectorForce’s applied

I think this should be possible since the new physics’ object’s evaluate in the internal physics step.

However, it would need to happen before the collision’s are processed. Since if it happened after the collisions are processed the velocity would change and no longer be the previous frame’s velocity.

So now my question is, are vectorforces solved before collision is solved?

1 Like

I don’t know these low-level implementation details, but I would imagine collisions are the last thing that gets solved because they are entirely dependent on everything that happens before.

1 Like

How did you solve the velocity from the delayed frame when just acting upon a collision? (since you set the previous frames velocity as the new velocity each step)

I didn’t set the previous frame’s velocity as the new velocity. The previous frame’s velocity was used to calculate the force of the air resistance.

1 Like

Oh I see. And the air resistance is constantly being changed. Ok!

1 Like