Camera Troubles (I don't understand CFrames very well)

Hey! I’m having a lot of trouble right now trying to make a camera that points towards the mouse. I want it to move smoothly around the screen, but with limitations so the player can’t look anywhere they want. It’s sort of hard to explain, but I want this:

(But with a greater range of where you can move your camera)

What I have right now does not do anything close to that
I have slightly modified code from another forum post that I tried asking ChatGPT for help with (to no avail)

My current non-functioning code:

---------- Services -----------

local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")

---------- Variables -----------

local Camera = workspace.CurrentCamera
local CameraPos = workspace:WaitForChild("CameraPos")
local Mouse = game:GetService("Players").LocalPlayer:GetMouse()
local LastMousePos = nil

local MaxX = 15
local MaxY = 15

---------- Code ----------

Camera.CameraType = Enum.CameraType.Scriptable

task.wait(2)

---------- Function to find where to look at ----------

local function FindLookDirection(MouseHit: CFrame)
	local LookCFrame = CFrame.lookAt(CameraPos.Position, MouseHit.Position)
	
	local RotX, RotY = LookCFrame:ToOrientation()
	RotX = math.deg(RotX)
	RotY = math.deg(RotY)
	
	print(RotX, RotY)
	
	local ClampedX = math.clamp(RotX, CameraPos.CFrame.LookVector.X - MaxX, CameraPos.CFrame.LookVector.X + MaxX)
	local ClampedY = math.clamp(RotY, CameraPos.CFrame.LookVector.Y - MaxX, CameraPos.CFrame.LookVector.Y + MaxX)
	
	return CameraPos.CFrame * CFrame.Angles(math.rad(ClampedX), math.rad(ClampedY), 0)
	
end

RunService.RenderStepped:Connect(function()
	if UIS:GetMouseLocation() ~= LastMousePos then
		LastMousePos = UIS:GetMouseLocation()
		local MouseHit = Mouse.Hit
		
		local TargetCFrame = FindLookDirection(MouseHit)
		
		TweenService:Create(Camera, TweenInfo.new(.25), {CFrame = TargetCFrame}):Play()
	end
end)

What this code does:

I think the big problem here is I don’t know a lot about CFrames. They are too confusing!!! Any help is appreciated!

You can use CFrame.LookAt() and calculate angle from it to see if it’s not above the limit, use head’s CFrame soo player can only look forward

What do you mean by use head’s cframe so player can only look forward? How would I do that. Also that code is already trying to use CFrame.lookat()

1 Like

I tried a different approach entirely, to little avail.

---------- Services -----------

local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")

---------- Variables -----------

local Camera = workspace.CurrentCamera
local CameraPos = workspace:WaitForChild("CameraPos")
local Mouse = game:GetService("Players").LocalPlayer:GetMouse()
local LastMousePos = nil

local MaxX = 50
local MaxY = 15

---------- Code ----------

Camera.CameraType = Enum.CameraType.Scriptable

task.wait(2)

Camera.CFrame = workspace.CameraPos.CFrame

---------- Function to find where to look at ----------

RunService.RenderStepped:Connect(function()
	if UIS:GetMouseLocation() ~= LastMousePos then
		LastMousePos = UIS:GetMouseLocation()
		local TargetCFrame = CFrame.lookAt(CameraPos.Position, Mouse.Hit.Position)
		print(TargetCFrame.LookVector)
		local ClampedX = math.clamp(TargetCFrame.LookVector.X, 0.3, .4)
		local ClampedY = math.clamp(TargetCFrame.LookVector.Y, -0.6, 0.6)
		
		Camera.CFrame = CFrame.lookAt(CameraPos.Position, (CameraPos.Position + Vector3.new(ClampedX, ClampedY, TargetCFrame.LookVector.Z)))
	end
end)

The result (at least it moves farther now I guess??)

I’m starting to get really annoyed. CFrames make zero sense to me. Lookvector can’t be assigned to and trying to print a cframes rotation prints just as many values as normally printing a cframe does.

1 Like

You can get Angle by doing

local x,y,z = CFrame.LookAt(Player.Head.CFrame.Position, mouse.Hit.Position):ToOrientation()
1 Like