The issue is that, at some point, you are perfectly facing the primary part (I believe?), and getting NAN. I improved the script and tried to debug like this, in StarterPlayerScripts (to avoid setting a new RenderStepped connection every time the character spawns).
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local LocalPlayer = Players.LocalPlayer
local camera = Workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
RunService.RenderStepped:Connect(function()
local root = LocalPlayer.Character and LocalPlayer.Character.PrimaryPart
if root == nil then
return
end
local cframe = CFrame.lookAt(root.Position + Vector3.new(0, 25, 0), root.Position)
print(cframe)
camera.CFrame = cframe
end)
As I suspect, the print eventually gives NAN.
Since you are only ever top down, you don’t need to use the second parameter of CFrame.new (rewritten here as CFrame.lookAt) at all.
local cframe = CFrame.new(root.Position + Vector3.new(0, 25, 0)) * CFrame.Angles(-math.pi / 2, 0, 0)
I can then just throw this on at the end:
root.CFrame = CFrame.lookAt(root.Position, Vector3.new(mouse.Hit.Position.X, root.Position.Y, mouse.Hit.Position.Z))
Finished code:
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local LocalPlayer = Players.LocalPlayer
local camera = Workspace.CurrentCamera
local mouse = LocalPlayer:GetMouse()
camera.CameraType = Enum.CameraType.Scriptable
RunService.RenderStepped:Connect(function()
local root = LocalPlayer.Character and LocalPlayer.Character.PrimaryPart
if root == nil then
return
end
camera.CFrame = CFrame.new(root.Position + Vector3.new(0, 25, 0)) * CFrame.Angles(-math.pi / 2, 0, 0)
root.CFrame = CFrame.lookAt(root.Position, Vector3.new(mouse.Hit.Position.X, root.Position.Y, mouse.Hit.Position.Z))
end)