BasePart.Position returns NaN value?

I’m trying to make a tank, and to get the turret to rotate towards the mouse im using a bodygyro and setting the cframe to CFrame.new(gunBase.Position, mouse.hit.p). It works great, but after a while of not moving the tank or turret, gunBase.Postion returns NaN and completely breaks the tank.

Thing’s I’ve tried:

checking if gunBase.Position == gunBase.Position because checking to make sure something is not equal to itself is the only way I know of to detect NaN. I only update the bodygyro cframe if it’s not nan, but it still breaks everything

I’ve tried iterating through a for loop that contains the components of the cframe, and if any of them are NaN, then I don’t update the cframe, but of course, this still breaks everything.

I’ve looked into a post by @dthecoolest Vector3 values become NAN after period of time that seemed like he had a very similar issue, but his problem seemed to come from getting the .Unit of a vector with 0 magnitude, which I don’t think is quite my issue.

Here’s the section of code:

runService:BindToRenderStep("Aim", 100, function()
	local startPosition = gunBase.Position
	local endPosition = mouse.hit.p
	
	if mobile then
		local unitRay = camera:ScreenPointToRay(crosshair.AbsolutePosition.X + crosshair.AbsoluteSize.X/2, crosshair.AbsolutePosition.Y + crosshair.AbsoluteSize.Y/2)
		local hit, hitPosition = workspace:FindPartOnRay(Ray.new(unitRay.Origin, unitRay.Direction * 5000), character)
		endPosition = hitPosition
	end
	
	if startPosition == startPosition then
		gunGyro.CFrame = CFrame.new(startPosition, endPosition)
	else
		print(startPosition)
	end
	
	local result = workspace:Raycast(muzzle.Position, muzzle.CFrame.RightVector * -5000, gunFilter)
	
	if result then
		local vector, onScreen = camera:WorldToViewportPoint(result.Position)
		crosshair.Visible = onScreen
		crosshair.Position = UDim2.fromOffset(vector.X, vector.Y)
	end
end)

If anyone has any idea on how to fix this or a better way to rotate a tank turret to your mouse, please let me know.

This code will not work if the raycast does not hit anything. The wiki states that:

If the ray does not intersect anything, the return values will be nil and the point at the end of the ray, respectively.

Which results in some NaN issues, cause endPosition cannot be nil.

Nice catch but wouldn’t this cause a nil error instead of a NAN error?

But additionally for my post I would like to add on it was this engine bug which caused the issue with humanoids.

An extremely small Vector3 value mixed with humanoids.

Otherwise yeah there could be a lot more other souces for NAN error it’s the worst type of problem there is.

That little chunk of code is just for players that are on mobile, so instead of using the mouse position, it puts a crosshair on their screen and gets the world position from that. I’ve never had an issue with endPosition so far. Everytime this bug has happened, it’s been from the startPosition, which is just “gunBase.Position” so I don’t get why that would return NaN

Do you think this could be an engine bug too? Because I’m stumped as to what could be causing something as simple as getting a position to return NaN

I see. Then this is probably related to mouse.Hit.p. Can you try this instead?

gunGyro.CFrame = CFrame.new(startPosition, startPosition + mouse.UnitRay.Direction)

mouse.Hit is not always defined if I am correct, but mouse.UnitRay is.

Another possible source of NAN error is indeed the CFrame.new here is how CFrame.new or CFrame.lookat functions internally which they removed from the CFrame page for some reason. As seen there is a .Unit there and I believe CFrames .Unit automatically like when you try to get a look vector it’s .Unit.

So it might error if start pos equals end position.

Idk got any humanoid scripts in your character?

It might even be the model just take a look at this old humanoid nan glitch with slopes:

I can’t say for certain, because this bug is inconsistent and sometimes takes a while to happen, but that actually seemed to have stopped it breaking. The only issue now is that that line of code doesn’t correctly aim the turret. It get’s near the mouse, but not aimed directly at it.

Edit: nvm… It just broke

I’ve tried checking to make sure if startPosition ~= endPosition but it still happens. And what do you mean by humanoid scripts in character? I don’t think I do, but I’m also not exactly sure what you mean. Like, a humanoid in the tank or…?

fyi the humanoid bug on that post has already been fixed

This is the incorrect method because of floating point numbers which happens with vectors. Like

Vector(1.00001,0,0) will not equal vector(1,0,0)

Try measuring the magnitude distance between start and end position instead.

@Wingboy0 yep just being extremely paranoid with humanoids lots of hours lost trying to debug their problems.

I tried it with the .magnitude > 1 before as well, it didnt work.

Is this the only script in this case?

Yeah, that’s the only script that messes with that CFrame. I have vehicles like humvees and jeeps but they don’t have a turret and they never break.

I tried changing it from runservice:BindToRenderStep to runservice.Heartbeat:Connect(function() to see if maybe it was trying to get the position before it was fully rendered or something? idk, i’m out of ideas and getting desperate. Anyways, that didn’t fix anything.

I am having the same issue, but its only happening to my mobile players.
When I place body movers into them, the hrp position will randomly return NaN values. This cuses my script to crash.

It isnt consistent, and sometimes wont happen for an extended period
but it only happens on mobile for me and when I place body movers.

Just a question, are you putting math.huge into the body movers?

I have seen errors in the past with math huge and body movers so just wondering.

No, the largest I am setting a body mover is 10^6, but I don’t think that seems too huge, I am checking for if a value is math.huge or -math.huge to simply set it to 0 if that happens.

	if not FlightGyro then	
		FlightGyro = Instance.new("BodyGyro")
		FlightGyro.Name = "FlightGyro"
		FlightGyro.P = (10 ^ 4.5)
		FlightGyro.D = 1000
		FlightGyro.maxTorque = Vector3.new(FlightGyro.P, FlightGyro.P, FlightGyro.P)
		local pos = Torso.CFrame.p * Vector3.new(0,1,0)
		FlightGyro.cframe = CFrame.new(pos,pos + (Torso.CFrame.lookVector * Vector3.new(10,0,10))) -- Torso.CFrame
	end
	
	if FlightVelocity then FlightVelocity:Destroy() end
	FlightVelocity = Instance.new("BodyVelocity")
	FlightVelocity.Name = "FlightVelocity"
	FlightVelocity.velocity = Vector3.new(0, 0, 0)
	FlightVelocity.P = (10 ^ 4)
	FlightVelocity.maxForce = (Vector3.new(1, 1, 1) * (10 ^ 6))
	if not FlyState then
		FlyState = Character:WaitForChild("Flags"):WaitForChild("FlyState")
	end