Math Help with Flying Script

I had a flying script, that used BodyGyro, and BodyVelocity.
I have tried to update it to use AlignOrientation and AlignPosition.

For some reason, at random camera angles, the ‘Simulation is Paused’ and studio seems to keep pausing to load content.

In the old script I had issues with NAN, but never could find the cause.
So I think that is the issue with this new script, having problems with invalid numbers.
There is no errors in the output though.

If anyone can look over this script, or run it under Starter Character Scripts, and let me know where the problem might be, I would appreciate it. Thanks.

Local Script under StarterCharacterScripts

local UserInputService = game:GetService("UserInputService")

local Player = game.Players.LocalPlayer
local Character =  Player.Character or Player.CharacterAdded:Wait()
local Humanoid : Humanoid = Character:WaitForChild("Humanoid")
local HRP : Part = Character.PrimaryPart
local Camera = game.Workspace.CurrentCamera

local AlignPosition = Instance.new("AlignPosition")
AlignPosition.Enabled = false
AlignPosition.Parent = HRP
AlignPosition.Mode = Enum.PositionAlignmentMode.OneAttachment
AlignPosition.RigidityEnabled = true
AlignPosition.ReactionForceEnabled = false
AlignPosition.Attachment0 = HRP:WaitForChild("RootAttachment")-- Instance.new("Attachment", HRP)
AlignPosition.Position = Vector3.new(0,0,0)

local AlignOrientation = Instance.new("AlignOrientation")
AlignOrientation.Enabled = false
AlignOrientation.Parent = HRP
AlignOrientation.AlignType = Enum.AlignType.AllAxes
AlignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment
AlignOrientation.RigidityEnabled = true
AlignOrientation.ReactionTorqueEnabled = false
AlignOrientation.Attachment0 = HRP:WaitForChild("RootAttachment")-- Instance.new("Attachment", HRP)
AlignOrientation.CFrame = HRP.CFrame


local flying = false

local CurrentSpeed : number = 2
local MaxSpeed : number = Humanoid.WalkSpeed * 1.875
local Inertia : number = (1 - (CurrentSpeed / MaxSpeed))
local Momentum : Vector3 = Vector3.zero
local LastMomentum : Vector3 = Vector3.zero
local TotalMomentum : number = 0
local Tilt : number = 0
local LastTilt : number = 0
local LastTiltF : number = 0
local FlyDuration : number = 0

function DoPhysics(eTime,cameraMode)
	local CamCF = Camera.CFrame
	local Movement = Vector3.new(0, 0, 0)
	local MoveDirection = Humanoid.MoveDirection

	if not cameraMode then
		CamCF = HRP.CFrame
	end

	CurrentSpeed = math.max(CurrentSpeed,0.2)

	if MoveDirection.Magnitude > 0 then --we are moving
		local cf = CFrame.new(Vector3.zero,CamCF.LookVector*Vector3.new(1,0,1))
		cf = cf:VectorToObjectSpace(MoveDirection+Vector3.new(0,0.2,0))
		Movement = CamCF:VectorToWorldSpace(cf.Unit * CurrentSpeed)
	end

	Momentum = ((Momentum * Inertia) + Movement)
	TotalMomentum = math.min(Momentum.Magnitude, MaxSpeed)

	-- Calculate Tilt
	local v = Momentum * Vector3.new(1,0,1)
	local v2 = LastMomentum * Vector3.new(1,0,1)

	Tilt = v.Unit:Cross(((v2).Unit)).Y
	local AbsoluteTilt = math.abs(Tilt)

	if AbsoluteTilt > 0.06 or AbsoluteTilt < 0.001 then
		if math.abs(LastTilt) > 0.001 then
			Tilt = (LastTilt * 0.96)
		else
			Tilt = 0
		end
	else
		Tilt = ((LastTilt * 0.9) + (Tilt * 0.1))
	end
	LastTilt = Tilt

	if TotalMomentum < 0.5 then
		Momentum = Vector3.zero
		TotalMomentum = 0
		AlignOrientation.CFrame = CFrame.new(Vector3.zero, HRP.CFrame.LookVector * Vector3.new(1,0,1)) 
	elseif TotalMomentum < 10 then
		AlignOrientation.CFrame = CFrame.new(Vector3.zero, Momentum * Vector3.new(1,0,1)) 
	else
		AlignOrientation.CFrame = CFrame.new(Vector3.zero, Momentum) * CFrame.Angles(0,0,(Tilt*-20))
	end

	AlignPosition.Position = HRP.Position + (Momentum)
	LastMomentum = Momentum
end

local function fly()
	flying = true
	AlignPosition.Position = HRP.Position
	AlignPosition.Enabled = true
	AlignOrientation.CFrame = HRP.CFrame
	AlignOrientation.Enabled = true
	Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
	local eTime = 0
	while flying do
		DoPhysics(eTime,true)
		eTime = task.wait()
	end
end

local function endFlying()
	flying = false
	Humanoid:ChangeState(Enum.HumanoidStateType.RunningNoPhysics)
	AlignPosition.Enabled = false
	AlignOrientation.Enabled = false
end

UserInputService.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then
		if not flying then
			Humanoid.Jump = true
			wait(.3)
			fly()
		else
			endFlying()
		end
	end
end)

2 Likes

it works perfectly fine for me. If you don’t want that issue, just go to workspace and uncheck StreamingEnabled

1 Like

Are you sure you didn’t accidentally put a breakpoint somewhere in the script?
image
(It looks like this red dot next to the line number)
To remove it, right click & click “Delete Breakpoint”

1 Like


Actually what if one of those ends up as a vector with all coords set to 0?
CFrame.new(vector, vector) is equivalent to CFrame.lookAt(origin, target)
If you pass two identical vectors, a rotation with NaN is returned.

1 Like

It does appear to be NAN issues. I did just a print of the cframes before being used in the AlignOrientation, and when it breaks, its printing a CFrame with position at origin and all rotation values as NAN.

So what can I do to keep these CFrames from going NAN?

Could be just normalizing the vectors. If you get .Unit of a Vector3.zero you will also get a NaN vector.

And as @ClientCooldown said, CFrame.lookAt also causes NaNs like that.
A quick way of fixing this is checking if the Magnitude of the vector is too low.

local forward = Momentum * Vector3.new(1,0,1)
if forward.Magnitude == 0 then
-- fallback to some safe orientation or skip
else
    AlignOrientation.CFrame = CFrame.new(Vector3.zero, forward)
end

Same could also be done for checking Tilt.

Thanks everyone for the information.