Need help on locking camera look direction to player head

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I made a first person game.
    I want to lock the camera to the players head. I want my camera’s y position and look direction to be determined by the player head, or humanoid root part, but the rest determined by my mouse. So if i have an animation that makes the player fall over and execute it, the camera will emulate what the head sees.

  2. What is the issue? Include screenshots / videos if possible!
    The Interpolate() built in function is almost extinct on roblox and i cant find sources that explain how i could build it.
    Heres a video of the camera i want to replicate. It was made by someone else online, but they did use the roblox game engine to do it.


    – sorry about the quality.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    This is my first script. It looks like it will work, and it does until you move the player.

local cam = workspace:WaitForChild("Camera")
local player = game:GetService("Players").LocalPlayer
local head = player.Character:WaitForChild("Head")
local Humanoid = player.Character:WaitForChild("Humanoid")
local HumanoidRootPart = player.Character:WaitForChild("HumanoidRootPart")

player.CameraMaxZoomDistance = 0

local endPoint = head.CFrame + head.CFrame.LookVector *5
cam.CameraType = Enum.CameraType.Scriptable
cam:Interpolate(head.CFrame, endPoint, .1)
head.Transparency = 1

And this is my second script that i made with a barbaric solution.
It creates 2 parts. 1 exactally in the players head and the other exactally a few blocks in front of the players head. Then welds them. Should work right? For some reason the weld resets the blocks position to the humanoidrootpart all over again. I tried remaking this script wtih the blocks not anchored, transparency 0 and not implementing the weld. The cam: interpolate worked fine.

local cam = workspace:WaitForChild("Camera")
local player = game:GetService("Players").LocalPlayer
local head = player.Character:WaitForChild("Head")
local Humanoid = player.Character:WaitForChild("Humanoid")
local HumanoidRootPart = player.Character:WaitForChild("HumanoidRootPart")

player.CameraMaxZoomDistance = 0

local camPart = Instance.new("Part", player.Character) camPart.Anchored = true camPart.CanCollide = false camPart.Massless = true camPart.Size = Vector3.new(1,1,1) camPart.Transparency = 0
local camPart1 = Instance.new("Part", player.Character) camPart1.Anchored = true camPart1.CanCollide = false camPart1.Massless = true camPart1.Size = Vector3.new(1,1,1) camPart1.Transparency = 0

camPart.Position = player.Character:WaitForChild("Head").Position
local weld = Instance.new("Weld", camPart) weld.Part0 = camPart weld.Part1 = HumanoidRootPart

camPart1.CFrame = HumanoidRootPart.CFrame + HumanoidRootPart.CFrame.LookVector * 5
camPart1.Position = Vector3.new(camPart1.Position.X, camPart.Position.Y, camPart1.Position.Z)
weld = Instance.new("Weld", camPart) weld.Part0 = camPart1 weld.Part1 = HumanoidRootPart

cam.CameraType = Enum.CameraType.Scriptable
cam:Interpolate(camPart.CFrame, camPart1.CFrame, .1)
head.Transparency = 1

Any help and advice will do thanks for reading :smiley:
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

2 Likes

why don’t you make a while wait() loop that sets the CFrame of the workspace.CurrentCamera to the head CFrame?

(could also be runservice.RenderStepped or any similar looping event)

how would i do that? And if i did, would it be a waste of a while loop? I though roblox was interpreted.

Well, I added my edit cause the edit is a better solution, for example something like

local rs = game:GetService("RunService")

local plr = game.Players.LocalPlayer


rs.RenderStepped:Connect(function()
   workspace.CurrentCamera.CFrame = plr.Character.Head.CFrame
end)
1 Like

All it does is spin the character around like crazy. And when i set the player.CameraMaxZoomDistance to like 50, its a little more stable but the mouse isn’t anchored to the center of the screen and the camera look angle is determined only by movement

So you’re saying it moves around randomly, not the same way the head does?

yes it shakes around even when i look at the server side, my character is standing completely still. I dont have any other scripts. Its just the default game with nothing from the tool box

Wait my character is spinning around on the server side… but why lol

it works fine for me, are you sure the head isn’t moving, like for example idle animation?

Yeah your solution works (i forgot CameraMaxZoomDistance = 0) but i want to be able to turn with my mouse and when i press a or d to move, it over spins

local RunService = game:GetService("RunService")

local player = game.Players.LocalPlayer
local char = player.CharacterAdded:Wait()
local camera = player.Camera

local function onUpdate()
    local headOffset = char.Head.CFrame:VectorWorldSpace(Vector3.new(0,0,-char.Head.Size.Z/2))
    camera.CFrame = char.Head.CFrame + headOffset
end

RunService:BindToRenderStep("UpdateCamera", Enum.RenderPriority.Camera, onUpdate)

try this

1 Like

i appreciate it, but it did nothing :frowning:

lol i just noticed the other guys solution is almost the same as this. what problems do u have with it

i want my camera look direction to be reflected by player mouse as well

edit: like in the video

1 Like
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")

local player = game.Players.LocalPlayer
local char = player.CharacterAdded:Wait()
local camera = player.Camera

local rotation = CFrame.Angles(0,0,0)
local function onUpdate()
    local delta = UserInputService:GetMouseDelta()
    rotation = rotation*CFrame.Angles(delta.Y, delta.X,0)

    local headOffset = char.Head.CFrame:VectorWorldSpace(Vector3.new(0,0,-char.Head.Size.Z/2))
    camera.CFrame = (char.Head.CFrame + headOffset)*rotation
end

RunService:BindToRenderStep("UpdateCamera", Enum.RenderPriority.Camera, onUpdate)

this will position the cframe with the head, as well as rotating it depending on your mouse movement
the signs on the angles might be a bit finicky, so lemme know how it works

3 Likes

thank you soo much it totally works! :smiley:

nice :slight_smile: you can change the sensitivity on the mouse movement by multiplying the delta like this: UserInputService:GetMouseDelta()*100

bigger number gives bigger sensitivity

1 Like

also another weird thing is i added a print(“hello”) inside function onUpdate(). It never prints hello but it works anyways lol.

are you sure its not just printing at the very top of the console as something like
hello (x234)
because renderstepped is really fast and thats how similar prints are displayed

also, if you wanted to turn the head with the mouse movement you could multiply the head CFrame by the rotation matrix instead

lol But yeah i think the hello was at the very top