First person camera following the head

Thank you, I’ve been trying to get this to work for about 5-6 hours since yesterday haha. I finally decided to make a post and it seems that I’m not the only one who finds it to be somewhat difficult. Thanks for the help.

Here is some code for this:

-- Put in StarterCharacterScripts
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")

local character = script.Parent
local head = character:WaitForChild("Head")
local neck = head:WaitForChild("Neck")
local hrp = character:WaitForChild("HumanoidRootPart")

character:WaitForChild("Humanoid").AutoRotate = false

local camera = Workspace.CurrentCamera

local player = game:GetService("Players"):GetPlayerFromCharacter(character)
-- Set the camera to first person
player.CameraMaxZoomDistance = 0

local beforeCFrame = camera.CFrame
local function afterCamera(delta)
	-- Calculate the amount to rotate the hrp from the camera input
	local beforeAngles = beforeCFrame - beforeCFrame.Position
	local afterAngles = camera.CFrame - camera.CFrame.Position
	local rx, ry, _ = beforeAngles:ToObjectSpace(afterAngles):ToEulerAnglesXYZ()
	hrp.CFrame = hrp.CFrame * CFrame.Angles(0, ry, 0)
	
	-- Calculate the amount to have the head look up or down
	neck.C0 = neck.C0 * CFrame.Angles(rx, 0, 0)
	
	-- Basic (Follows head exactly)
	--camera.CFrame = head.CFrame
	
	-- No tilt (Makes it so the camera doesn't tilt)
	camera.CFrame = CFrame.lookAt(head.Position, head.Position + head.CFrame.LookVector)
	-- Might need some code to limit the angle around looking exactly up and down otherwise there might be some character rotation
end

local function beforeCamera(delta)
	beforeCFrame = camera.CFrame
end

RunService:BindToRenderStep("Before camera", Enum.RenderPriority.Camera.Value - 1, beforeCamera)
RunService:BindToRenderStep("After camera", Enum.RenderPriority.Camera.Value + 1, afterCamera)

You might need some specific animations to reduce the bounciness (the head moves around a bit while walking with the normal animations).

You could also add some smoothing/lerping to reduce the bouncing.

It’s working better, but it still spazzes out a ton. Thanks for the help, I may just follow the position and not the rotation of the head. This is kinda complicated and doesn’t want to work right so far. Thanks again for the help. Does it work properly for you? if it does and doesn’t start spinning than maybe it has to do with one of my other scripts, I could change them if needed.

Edit:

Just tested it in a blank game and it works, I’ll have to see what’s interfering. It does make the camera Y movement inverted though, any idea why it’s doing that and/or how to fix it?

Thank you! Now I just have to find what is interfering with it and fix it, also, just in case anyone else finds this solution. The neck variable should be ‘local neck = torso:WaitForChild(“Neck”)’

Just make sure to have it looking in the torso not the head.

1 Like