How do i make the player's head move with the camera

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 want to make the player’s body move with the camera

  2. What is the issue? Include screenshots / videos if possible!
    The head moves the wrong direction when you turn your body

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I couldn’t find anything about this, i tried:

  • removing the math.asin
  • subtracting the humanoid rootparts cframe’s X lookvector from the one of the camera (which works except that when you move your head 90 degrees in any direction (from the world rotation) it starts going back which it should but only from the rootpart’s rotation)

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

This is what i have so far:

local plr = game.Players.LocalPlayer
local neckC0 = CFrame.new(0, 0.8, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1);
local waistC0 = CFrame.new(0, 0.2, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1);

local function onUpdate(dt)
    if plr.Character ~= nil then
	local camera = workspace.CurrentCamera;
	local body = plr.Character.HumanoidRootPart
	if plr.Character.Head.Neck ~= nil then --neck joint is not broken
	    if plr.Character.UpperTorso:FindFirstChild("Waist") ~= nil then
		local neck = plr.Character.Head.Neck;
		local waist = plr.Character.UpperTorso.Waist;
		local theta = math.asin(camera.CFrame.LookVector.y)
		local theta2 = math.asin(camera.CFrame.LookVector.x-body.CFrame.LookVector.X)

		neck.C0 = neckC0 * CFrame.Angles(theta*0.5, -theta2, 0);
		CFrame.new()
    		waist.C0 = waistC0 * CFrame.Angles(theta*0.5, 0, 0);
	    end
        end
    end
end
game:GetService("RunService").RenderStepped:Connect(onUpdate);

Here is a video showing what it does now
Reddit post with the video because i can’t upload it to here
(don’t mind my character nor the video quality)

9 Likes

Welcome to the community, ketrab2004! :slight_smile:
I believe that you are having trouble calculating your theta2 angle correctly. A method of finding it is shown in the diagram below. (x,y) in your case are the X and Z components of the camera and body CFrame LookVectors.
image
This is usually done through the math function math.atan2.

We can get the angle that the camera is pointing towards like so:

local camera_angle = math.atan2(camera.CFrame.LookVector.X, camera.CFrame.LookVector.Z)

We can get the angle that the body is pointing towards like so:

local body_angle = math.atan2(body.CFrame.LookVector.X, body.CFrame.LookVector.Z)

Your angle theta2 can be found by taking body_angle from the camera_angle:

local theta2 = camera_angle-body_angle

Also, theta2 no longer needs to be negated inside the CFrame.Angles constructor.
Hope this helps, let me know if there are any issues. :slight_smile:

4 Likes

Thanks this works great, but right now you can do a 360 with your head.
I tried putting a if on the camera_angle-body_angle, but it stops working when you turn your body.

if theta2 >= math.pi/2 and theta2 <= math.pi then
  theta2 = math.pi/2
elseif theta2 <= math.pi*1.5 and theta2 >= math.pi then
  theta2 = -math.pi/2
end
3 Likes

I see the issue, and I think we can fix that through the following:

local theta2 = (camera_angle-body_angle)%(2*math.pi)

This essentially bounds theta2 so that we have persistent angles for any rotation of the body.

if theta2 > math.pi/2 and theta2 < math.pi*1.5 then
	theta2 = math.pi-theta2
end

Finally we can just flip the value of theta2 as it moves past these limits to give a nice returning head effect I have seen in some games.
Hope this helps :slight_smile:

6 Likes

Thank you so much for the help, it works great now
:slightly_smiling_face:

2 Likes

If you want the Head of the player to look to the direction where the camera is looking at. You have to say:

Blockquote
neck.C0 = neckC0 * CFrame.Angles(theta*0.5, theta2, 0);

Instead of:

Blockquote
neck.C0 = neckC0 * CFrame.Angles(theta*0.5, -theta2, 0);