Advice on scripting realistic flying physics

Hello, I am attempting to create a script to turn the player when they are flying.

So far, I’ve already scripted the flying, and I’m using Body Gyro for the dampening of the rotation of the movement. Everything is that department is solved, but I’m trying to do something a little extra tricky. I’m attempting to make it so, during a sharp turn (depending of the sharpness of the turn), the player “dips” into the turn.

BodyGryo and BodyVelocity instances were placed into the HumanoidRootPart previous to this part of the script. This section of the script is what loops during the flying itself:

local dir = workspace.CurrentCamera.CFrame.LookVector.Z
while Flying do
	BodyVelocity.Velocity = workspace.CurrentCamera.CFrame.lookVector*(flyspeed)
	local z = dir-workspace.CurrentCamera.CFrame.LookVector.Z
	BodyGyro.CFrame = workspace.CurrentCamera.CFrame
	HumanoidRootPart.CFrame = HumanoidRootPart.CFrame*CFrame.Angles(0,0,z)
	dir = workspace.CurrentCamera.CFrame.LookVector.Z

So far this works okay. The body movement dampens the turn, but the “dipping” part is giving me issues. While making a continuous turn, the character wobbles left and right, instead of staying in the correct position. This might have something to do with how I’m setting up z to be the difference of the camera’s LookVector between frames, but how else should I attempt this?

Thank you!!

EDIT: I’m sorry if this is off topic, but it relates to this. Is there a way to make it so Roblox in-game video recordings save as .mp4 instead of .wmv? The .wmv format is not compatible with upload to a lot of websites, including here. I want to show a video of the problem. Thanks again.


The easiest solution would be to use BodyForces. One for movement, another for air drag.
A slightly more complex solution would be to manipulate the MaxForce property of you BodyVelocity.

You can’t change the format, but you can convert it with a program like Handbrake. Use OBS instead as the built in recorder is slow and low quality.


Can you give me an example/breakdown of how this works? Thanks!

In past experiences, if you truly want to have full control over the momentum and achieve as realistic controls as you are willing to make, scripting a custom physics engine designed to handle that sort of stuff is the best way to go.

A good example of this would be to keep track of forward velocity and increase/decrease it based on Throttle, The way the vehicle is angled, wind resistance, and anything else you may want to add in. Then, once all the equations have been run, just set the CFrame of the model.

Note: This will only work if the model is Anchored, or if everything is welded to one part then if that part is anchored. Otherwise Roblox physics will still intervene and give very unrealistic and undesired outcomes.


I’m not planning to make incredibly realistic momentum, but just for now working on basics, like the body tilting into a turn. I almost had it before with it almost working the way i wanted it to with the small problem that it was wobbling instead of staying in the right position.

Everything in the model is welded to a single “Root” part, but this root part, if its anchored, it stops moving.

Is this impossible to do with the BodyGyro setup I have? If so, what’s a better method to do it with? I don’t know much about the Body instances so I’m trying everything I can to understand them better.

Quick question: are you using the mouse to control movement or the WASD keys?

I’m using the mouse. The movement of the body goes continuously in the direction of the looking direction of the player’s camera.

So, if you’re making the body gyro just point towards the mouse you can take the classic crazyman32 plane approach, where you tilt the rotation of the body gyro based on the mouses x position on the screen.

Perfect then, you can try to use the RocketPropulsion body mover. It’s a hybrid of BodyGyro and BodyPosition.

What you can do now is make the Part that the model is welded to face where the camera is pointing and move in that direction at the same time.

Also, here’s the Wiki page.

Second edit: Each time the model rotates using Bodygyro or something else. Get the previous point that the screen was facing and compare it to the spot it currently is pointing at. You can use this to find the intensity of the dip you want the model to make.

Por ejemplo: Screen is facing A. Player flicks the screen to face B real quick. The difference is high. So, you roll the model by a big amount. Rolling is rotating but on the side.

1 Like

Best I can do tonight at 12:58. Good luck!

This helped a lot! But I’m having a problem. It won’t let me set the Target as the lookVector of the camera. How do I do this?

That’s most likely because it’s asking for Vector3 Position, and not a Vector3 direction.
You can add the lookvector to the player’s position and the direction is now turned into a position. Which can be placed as a target.

If that position does not work, then the Target is asking for an object. In which case have a block at the position that we made above and place the Target as that block.

Try using raycast from the camera position (or make a camera Part, that turns with camera movement, to raycast from. You can use the lookVector of the Part or camera for the raycast direction. Also, make sure the raycast length is long. I’d say 2000 studs for big maps.

So I went back to my original setup since that one was the simplest and it almost works perfectly, except for the fact that it can’t determine the direction the character is looking relative to itself, it can only determine its global direction with the LookVector of the camera. So, this is causing the wobbling effect. It is able to determine the sharpness of the turn, but not the direction, so it’s calculating the direction globally, not locally (character’s left vs character’s right).

Setup similar to my original post: BodyGryo is being used to turn the body of the player while in the flying state, BodyVelocity is handling the flying itself (and the speed)

local dir = workspace.CurrentCamera.CFrame.LookVector.Z
while Flying do
	Bv.Velocity = workspace.CurrentCamera.CFrame.lookVector*(flyspeed)
	local z = (dir-workspace.CurrentCamera.CFrame.LookVector.Z)*20 -- difference of the look direction of this frame compared to the last rendered frame. 0 means player looking straight, higher number mean player turned more quickly
	Bg.CFrame = workspace.CurrentCamera.CFrame*CFrame.Angles(0,0,z) -- turning the player left/right depending on how sharply they turn in a direction. 0 means no turn applied
	dir = workspace.CurrentCamera.CFrame.LookVector.Z

How can I determine if “dir” is left or right from the local character? z becomes positive or negative depending on the global orientation of the camera.

How can I be able to determine something like:

if dir == left then ____ end
if dir == right then ____ end

thank you for the help!