How can I fix the camera not sticking to the head despite only using :lookAt()?

My camera for whatever reason does not stick to the character’s head, despite using CFrame:lookAt()

the camera will not be attached to the head for a split second

somebody please help me out with this i hate camera scripting

video of what’s happening:


and the code (don’t worry about the length of it, all of the functions serve the same purpose!!!):

local tService = game:GetService("TweenService")
local tweenParameters = TweenInfo.new(
	0.15,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.Out
)

local scalingFactor = 0.05

local cameraFunctions = {
	FirstComboSwing = function(camera: Camera, char: Model)
		local head = char:FindFirstChild("Head")
		local originalCFrame = camera.CFrame
		local targetLookAtPosition = head.Position + Vector3.new(-10, -0.5, 0) * scalingFactor

		local targetCFrame = CFrame.lookAt(camera.CFrame.Position, targetLookAtPosition)

		camera.CFrame = targetCFrame		
		local shiftCameraBack = tService:Create(camera, tweenParameters, {CFrame = originalCFrame})
		shiftCameraBack:Play()
	end,

	SecondComboSwing = function(camera: Camera, char: Model)
		local head = char:FindFirstChild("Head")
		local originalCFrame = camera.CFrame
		local targetLookAtPosition = head.Position + Vector3.new(5, 0.5, 0) * scalingFactor

		local targetCFrame = CFrame.lookAt(camera.CFrame.Position, targetLookAtPosition)

		camera.CFrame = targetCFrame		
		local shiftCameraBack = tService:Create(camera, tweenParameters, {CFrame = originalCFrame})
		shiftCameraBack:Play()
	end,

	ThirdComboSwing = function(camera: Camera, char: Model)
		local head = char:FindFirstChild("Head")
		local originalCFrame = camera.CFrame
		local targetLookAtPosition = head.Position + Vector3.new(-10, -0.5, 0) * scalingFactor

		local targetCFrame = CFrame.lookAt(camera.CFrame.Position, targetLookAtPosition)

		camera.CFrame = targetCFrame		
		local shiftCameraBack = tService:Create(camera, tweenParameters, {CFrame = originalCFrame})
		shiftCameraBack:Play()
	end,

	HeavySwing = function(camera: Camera, char: Model)
		local head = char:FindFirstChild("Head")
		local originalCFrame = camera.CFrame
		local targetLookAtPosition = head.Position + Vector3.new(0.5, -0.5, 0) * scalingFactor

		local targetCFrame = CFrame.lookAt(camera.CFrame.Position, targetLookAtPosition)

		camera.CFrame = targetCFrame		
		local shiftCameraBack = tService:Create(camera, tweenParameters, {CFrame = originalCFrame})
		shiftCameraBack:Play()
	end,
}

local cameraManipulationModule = {}

function cameraManipulationModule.Manipulate(camera: Camera, manipulationType: string, char: Model)
	cameraFunctions[manipulationType](camera, char)
end

return cameraManipulationModule
1 Like

Did you try using RunService to constantly update the camera’s position to the head?

local function lockCameraFocus()
			Camera.CameraType = Enum.CameraType.Scriptable
			
			RunService:BindToRenderStep("CameraLockOn", Enum.RenderPriority.Camera.Value, function() -- This simply locks the camera
				Camera.CFrame = CFrame.lookAt(Focus.Position, rootPart.Position) -- Locks the camera at the part's position while following wherever the HumanoidRootPart goes
			end)
		end
		
		
		local function unlockCameraFocus()
			Camera.CameraType = Enum.CameraType.Custom
			RunService:UnbindFromRenderStep("CameraLockOn") -- This simply unlocks the camera
		end
		
		lockCameraFocus()
		
		task.wait(4)
	
		unlockCameraFocus()

This guy also helped me out a lot.

Here’s the full post:

yes, yes i have

i’ve tried it with two things

  1. Setting the camera CFrame to the targetCFrame, the results are this:

  1. Setting the camera CFrame to the head CFrame, the results are this:

and the code looks like this (head CFrame variant, targetCFrame variant not included):

local rService = game:GetService("RunService")
local tService = game:GetService("TweenService")
local tweenParameters = TweenInfo.new(
	0.15,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.Out
)

local scalingFactor = 0.05

local cameraFunctions = {
	FirstComboSwing = function(camera: Camera, char: Model)
		local head = char:FindFirstChild("Head")
		local originalCFrame = camera.CFrame
		local targetLookAtPosition = head.Position + Vector3.new(-10, -0.5, 0) * scalingFactor

		local targetCFrame = CFrame.lookAt(camera.CFrame.Position, targetLookAtPosition)

		camera.CFrame = targetCFrame		
		local shiftCameraBack = tService:Create(camera, tweenParameters, {CFrame = originalCFrame})
		shiftCameraBack:Play()
		
		rService:BindToRenderStep("StickCameraToHead", Enum.RenderPriority.Camera.Value, function()
			camera.CFrame = head.CFrame
		end)
		
		local tweenConnection
		
		tweenConnection = shiftCameraBack.Completed:Connect(function()
			rService:UnbindFromRenderStep("StickCameraToHead")
			tweenConnection:Disconnect()
		end)
	end,

	SecondComboSwing = function(camera: Camera, char: Model)
		local head = char:FindFirstChild("Head")
		local originalCFrame = camera.CFrame
		local targetLookAtPosition = head.Position + Vector3.new(5, 0.5, 0) * scalingFactor

		local targetCFrame = CFrame.lookAt(camera.CFrame.Position, targetLookAtPosition)

		camera.CFrame = targetCFrame		
		local shiftCameraBack = tService:Create(camera, tweenParameters, {CFrame = originalCFrame})
		shiftCameraBack:Play()
		
		rService:BindToRenderStep("StickCameraToHead", Enum.RenderPriority.Camera.Value, function()
			camera.CFrame = head.CFrame
		end)

		local tweenConnection

		tweenConnection = shiftCameraBack.Completed:Connect(function()
			rService:UnbindFromRenderStep("StickCameraToHead")
			tweenConnection:Disconnect()
		end)
	end,

	ThirdComboSwing = function(camera: Camera, char: Model)
		local head = char:FindFirstChild("Head")
		local originalCFrame = camera.CFrame
		local targetLookAtPosition = head.Position + Vector3.new(-10, -0.5, 0) * scalingFactor

		local targetCFrame = CFrame.lookAt(camera.CFrame.Position, targetLookAtPosition)

		camera.CFrame = targetCFrame		
		local shiftCameraBack = tService:Create(camera, tweenParameters, {CFrame = originalCFrame})
		shiftCameraBack:Play()
		
		rService:BindToRenderStep("StickCameraToHead", Enum.RenderPriority.Camera.Value, function()
			camera.CFrame = head.CFrame
		end)

		local tweenConnection

		tweenConnection = shiftCameraBack.Completed:Connect(function()
			rService:UnbindFromRenderStep("StickCameraToHead")
			tweenConnection:Disconnect()
		end)
	end,

	HeavySwing = function(camera: Camera, char: Model)
		local head = char:FindFirstChild("Head")
		local originalCFrame = camera.CFrame
		local targetLookAtPosition = head.Position + Vector3.new(0.5, -0.5, 0) * scalingFactor

		local targetCFrame = CFrame.lookAt(camera.CFrame.Position, targetLookAtPosition)

		camera.CFrame = targetCFrame		
		local shiftCameraBack = tService:Create(camera, tweenParameters, {CFrame = originalCFrame})
		shiftCameraBack:Play()
		
		rService:BindToRenderStep("StickCameraToHead", Enum.RenderPriority.Camera.Value, function()
			camera.CFrame = head.CFrame
		end)

		local tweenConnection

		tweenConnection = shiftCameraBack.Completed:Connect(function()
			rService:UnbindFromRenderStep("StickCameraToHead")
			tweenConnection:Disconnect()
		end)
	end,
}

local cameraManipulationModule = {}

function cameraManipulationModule.Manipulate(camera: Camera, manipulationType: string, char: Model)
	cameraFunctions[manipulationType](camera, char)
end

return cameraManipulationModule

i’ll bump this incase someone else knows how to help :^)

I just made two functions, one that locks the camera and the other that unlocks the camera. Then I waited about 4 seconds, then unlocked the camera.

LockCamera()
task.wait(4) -- Put your preferred amount here.
UnlockCamera()

Just keep trying. You’ll get your solution sooner or later.

From the looks of the video… think I was wrong here…

local camera = workspace.CurrentCamera
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")

task.wait(4) -- wait test
local cameraPosition = head.Position + Vector3.new(0, 10, -20)
camera.CFrame = CFrame.new(cameraPosition, head.Position)

Not seeing any shake with tools

ugh…

is there a way to just change the camera’s look angle without changing the entire cframe of it :frowning:

maybe

local camera = workspace.CurrentCamera
local currentCFrame = camera.CFrame
local rotation = CFrame.Angles(0, math.rad(45), 0)
camera.CFrame = CFrame.new(currentCFrame.Position) * rotation

Not really seeing that kind of motion setting a cam to the head, without this.

Have you actually disabled Roblox’s camera scripts? I don’t see any RunService binding in your original code, which makes me think you have tweens fighting with the regular camera RenderStepped update. FWIW, you probably don’t want the world space offsets you’re using, nor do you want a tween that’s tweening a world space CFrame, since your character is moving!

uhhhh, no


i didn’t really think it was gonna be useful since all i wanted to change was what the camera is looking at