Good day! I am trying to make a script where the first person camera doesnt pitch up or down so the player can only look left and right but nothing im doing is working!
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local camera = game.Workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
local function updateCamera()
local lookVector = humanoid.MoveDirection
lookVector = lookVector:Cross(Vector3.new(0,1,0)):Cross(Vector3.new(0,1,0))
camera.CFrame = CFrame.new(character.Head.Position, character.Head.Position + lookVector)
end
updateCamera()
game:GetService("RunService").RenderStepped:Connect(function()
updateCamera()
end)
Hello! It seems that you want to restrict the camera’s pitch so that the player can only look left and right. One way to achieve this is to set the camera’s CFrame to always point towards the character’s position, but with a fixed offset for the pitch.
Here’s an updated version of your script that implements this:
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local camera = game.Workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
local fixedPitch = math.rad(20) -- change this to adjust the pitch offset
local function updateCamera()
local lookVector = humanoid.MoveDirection
lookVector = lookVector:Cross(Vector3.new(0,1,0)):Cross(Vector3.new(0,1,0))
local rotation = CFrame.Angles(fixedPitch, 0, 0)
camera.CFrame = CFrame.new(character.Head.Position) * rotation * CFrame.new(lookVector * 10)
end
updateCamera()
game:GetService("RunService").RenderStepped:Connect(function()
updateCamera()
end)
In this version, the fixedPitch variable determines the pitch offset in radians. The updateCamera function first calculates the look vector as before, then creates a rotation matrix using the CFrame.Angles method to apply the pitch offset. The camera’s CFrame is then set to the character’s head position, followed by the rotation and a translation along the look vector multiplied by a distance factor (in this case, 10).
Note that this implementation assumes that the player is always standing upright and facing forward, and that the camera is initially positioned behind the character. If these assumptions are not true, you may need to adjust the calculations accordingly.
You can piggy-back off of the built-in camera scripts by not overwriting the CameraType of the camera and then binding your update function to fire immediately after them. By getting the components of the camera’s rotational CFrame, you can only apply the rotation about the y-axis and discard the rest to lock the camera to the x-z plane:
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local camera = game.Workspace.CurrentCamera
local function updateCamera()
local camera_cframe = camera.CFrame
camera.CFrame = CFrame.new(camera_cframe.Position) * CFrame.Angles(0, (select(2, camera_cframe:ToEulerAnglesYXZ())), 0)
end
updateCamera()
game:GetService("RunService"):BindToRenderStep("LockToPlane", Enum.RenderPriority.Camera.Value + 1, updateCamera)