The main issue is that trying to rotate my camera on the X-axis gives unexpected results, as seen here
I’ve done many google searches and nothing has shown to be successful yet.
local nN = math.rad(-85)
local pN = math.rad(85)
-- stuffs
do
local delta = UIS:GetMouseDelta()
local x,y,z = camera.CFrame:ToOrientation()
local hx,hy,hz = char.HumanoidRootPart.CFrame:ToOrientation()
local ang = CFrame.Angles(
math.clamp( -- I can confirm that math.clamp isn't the issue
x + math.rad(-delta.Y/2),
hx + nN,
hx + pN
),
math.clamp(
y + math.rad(-delta.X/2),
hy + nN,
hy + pN
),
0
)
camera.CFrame = CFrame.new(char.Head.Position) * ang
end
The problem is that rotating a CFrame that way rotates it relative to how it’s already rotated. If you pitch up, then try to yaw in either direction, you’ll be yawing relative to the current CFrame. That means rotating around the object-space Y axis of the current CFrame. It’s not pointing straight up, so you get a weird compound rotation.
You fix this by rotating around the correct axes. You can rotate about a specific axis by doing
--set position while leaving rotation unchanged
camera.CFrame = camera.CFrame - camera.CFrame.p + char.Head.Position
--pitch
local rightAxis = camera.CFrame.RightVector --valid since the camera should never have any roll / Z rotation, so the object-space RightVector never points a little bit up/down in world space
camera.CFrame *= CFrame.fromAxisAngle(rightAxis, delta.X)
--comes out to the exact same as camera.CFrame *= CFrame.Angles(delta.X, 0, 0)
--yaw
local upAxis = camera.CFrame:VectorToObjectSpace( Vector3.new(0, 1, 0) )
camera.CFrame *= CFrame.fromAxisAngle(upAxis, delta.Y)
Let me know if this works. I’m writing this from what I remember, since I recently had to do this in my own project. It might not be 100% correct tho