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