Custom head movement isnt working?

hello devs!, I’m reaching out to ask for help because I’ve hit a roadblock. I’m aware of the possibility I haven’t set it up right and hoping its not a code error as it was working before I finalized it. ive tried an assortment of things and have been unsuccessful. this is what it all looks like in workspace.

here is the code im using
headmovement

local tweenService = game:GetService("TweenService")

local Camera = workspace.CurrentCamera
local Player = game.Players.LocalPlayer

local Character = Player.Character
local Root = Character:WaitForChild("HumanoidRootPart")
local Neck = Character:FindFirstChild("Neck", true)
local YOffset = Neck.C0.Y

local CFNew, CFAng = CFrame.new, CFrame.Angles
local asin = math.asin

game:GetService("RunService").RenderStepped:Connect(function()
	local CameraDirection = Root.CFrame:toObjectSpace(Camera.CFrame).lookVector
	if Neck then
		if Character.Humanoid.RigType == Enum.HumanoidRigType.R15 then
			Neck.C0 = CFNew(0, YOffset, 0) * CFAng(0, -asin(CameraDirection.x), 0) * CFAng(asin(CameraDirection.y), 0, 0)
		elseif Character.Humanoid.RigType == Enum.HumanoidRigType.R6 then
			Neck.C0 = CFNew(0, YOffset, 0) * CFAng(3 * math.pi/2, 0, math.pi) * CFAng(0, 0, -asin(CameraDirection.x)) * CFAng(-asin(CameraDirection.y), 0, 0)
		end
	end
end)

game.ReplicatedStorage.Look.OnClientEvent:Connect(function(otherPlayer, neckCFrame)
	local Neck = otherPlayer.Character:FindFirstChild("Neck", true)
	Neck.C0 = neckCFrame
end)

while wait(0.1) do
	game.ReplicatedStorage.Look:FireServer(Neck.C0)
end

camera client

wait(0)
local InputService=game:GetService("UserInputService")
local Camera=game.Workspace.CurrentCamera
local Player=game.Players.LocalPlayer
local Character=Player.Character
local Head=Character.Head
local Torso=Character.Torso
local RootPart=Character.HumanoidRootPart
local RootJoint=RootPart.RootJoint
local Neck=Torso.Neck
if InputService.TouchEnabled then
	script:Destroy()
end
Camera.FieldOfView=90
Camera.CameraType="Scriptable"
InputService.MouseBehavior=Enum.MouseBehavior.LockCenter


local v3=Vector3.new
local cf=CFrame.new
local components=cf().components
local inverse=cf().inverse
local fromAxisAngle=CFrame.fromAxisAngle
local atan,atan2=math.atan,math.atan2
local acos=math.acos

local function toAxisAngleFromVector(v)
	local z=v.z
	return z*z<0.99999 and v3(v.y,-v.x,0).unit*acos(-z) or v3()
end

local function AxisAngleLookOrientation(c,v,t)--CFrame,Vector,Tween
	local c=c-c.p
	local rv=(inverse(c)*v).unit
	local rz=rv.z
	return rz*rz<0.99999 and c*fromAxisAngle(v3(rv.y,-rv.x,0),acos(-rz)*(t or 1)) or c
end

local function AxisAngleLookNew(v,t)--CFrame,Vector,Tween
	local rv=v.unit
	local rz=rv.z
	return rz*rz<0.99999 and fromAxisAngle(v3(rv.y,-rv.x,0),acos(-rz)*(t or 1)) or cf()
end

local function AxisAngleLook(c,v,t)--CFrame,Vector,Tween
	local rv=(inverse(c)*v).unit
	local rz=rv.z
	return rz*rz<0.99999 and c*fromAxisAngle(v3(rv.y,-rv.x,0),acos(-rz)*(t or 1)) or c
end




local Sensitivity=0.005


local CameraDirection=Vector3.new(0,0,1)

local function EulerAnglesYX(l)
	local x,z=l.x,l.z
	return atan(l.y/(x*x+z*z)^0.5),-atan2(x,-z)
end

local function AnglesXY(l)
	local z=l.z
	return atan2(l.y,-z),-atan2(l.x,-z)
end

local function MouseMoved(Input)
	if Input.UserInputType==Enum.UserInputType.MouseMovement then
		local dx,dy=Input.Delta.x*Sensitivity,Input.Delta.y*Sensitivity
		local m2=dx*dx+dy*dy
		if m2>0 then
			CameraDirection=(AxisAngleLookOrientation(RootPart.CFrame,CameraDirection)*fromAxisAngle(v3(-dy,-dx,0),m2^0.5)).lookVector
		end
		local RootOrientation=RootPart.CFrame-RootPart.Position
		local RelativeDirection=RootOrientation:inverse()*CameraDirection
		local AngX,AngY=AnglesXY(RelativeDirection)--RootOrientation:inverse()*
		if AngX<-1.57*11/12 then
			local y,z,c,s=RelativeDirection.y,RelativeDirection.z,math.cos(-1.57*11/12-AngX),-math.sin(-1.57*11/12-AngX)
			z,y=z*c-y*s,z*s+y*c
			CameraDirection=RootOrientation*v3(RelativeDirection.x<0 and -(1-y*y-z*z)^0.5 or (1-y*y-z*z)^0.5,y,z)
		elseif AngX>1.57*11/12 then
			local y,z,c,s=RelativeDirection.y,RelativeDirection.z,math.cos(1.57*11/12-AngX),-math.sin(1.57*11/12-AngX)
			z,y=z*c-y*s,z*s+y*c
			CameraDirection=RootOrientation*v3(RelativeDirection.x<0 and -(1-y*y-z*z)^0.5 or (1-y*y-z*z)^0.5,y,z)
		end
	end
end

local Mouse=Player:GetMouse()

local Zoom=-0.5


InputService.InputChanged:connect(MouseMoved)

Neck.C1=cf()

local _
local DirectionBound=3.14159/3
local CurrentAngY=0

local function CameraUpdate()
	Camera.CameraType="Scriptable"
	local cx,cz=CameraDirection.x,CameraDirection.z
	local rvx,rvz=RootPart.Velocity.x,RootPart.Velocity.z
	if rvx*rvx+rvz*rvz>4 and cx*rvx+cz*rvz<-0.5*(cx*cx+cz*cz)^0.5*(rvx*rvx+rvz*rvz)^0.5 then
		DirectionBound=math.min(DirectionBound*0.9,math.abs(CurrentAngY*0.9))
	else
		DirectionBound=DirectionBound*0.1+3.14159/3*0.9
	end
	local AngX,AngY=EulerAnglesYX((RootPart.CFrame-RootPart.Position):inverse()*CameraDirection)
	if AngY>DirectionBound then
		RootPart.CFrame=RootPart.CFrame*CFrame.Angles(0,AngY-DirectionBound,0)
	elseif AngY<-DirectionBound then
		RootPart.CFrame=RootPart.CFrame*CFrame.Angles(0,AngY+DirectionBound,0)
	end
	_,CurrentAngY=EulerAnglesYX((RootPart.CFrame-RootPart.Position):inverse()*CameraDirection)
	local CameraOrientation=AxisAngleLookNew((RootPart.CFrame-RootPart.Position):inverse()*CameraDirection,1)
	Neck.C0=CFrame.new(0,1,0)*CameraOrientation*CFrame.new(0,0.5,0)
	local PreCam=AxisAngleLook(RootPart.CFrame*cf(0,1,0),RootPart.CFrame*v3(0,1,0)+CameraDirection)*CFrame.new(0,0.825,0)
	if Zoom==8 then
		local Part,Position=workspace:findPartOnRay(Ray.new(PreCam.p,PreCam.lookVector*-8),Character)
		Camera.CoordinateFrame=PreCam*CFrame.new(0,0,(Position-PreCam.p).magnitude)
	else
		Camera.CoordinateFrame=PreCam*CFrame.new(0,0,Zoom)
	end
end

game:GetService("RunService").RenderStepped:connect(CameraUpdate)

this is the error i get when i run the game
10:54:00.645 Head is not a valid member of Workspace “Workspace” - Server - CameraServer:7

2 Likes

ill also add the other 3 scripts i havent added above
CameraServer

wait(0)

local InputService=game:GetService("UserInputService")
local Camera=game.Workspace.CurrentCamera
local Character= script.Parent.Parent
local Player = game.Players:GetPlayerFromCharacter(Character)
local Head=Character.Head
local Torso=Character.Torso
local RootPart=Character.HumanoidRootPart
local RootJoint=RootPart.RootJoint
local Neck=Torso.Neck
Camera.FieldOfView=85
Camera.CameraType="Scriptable"
InputService.MouseBehavior=Enum.MouseBehavior.LockCenter



local v3=Vector3.new
local cf=CFrame.new
local components=cf().components
local inverse=cf().inverse
local fromAxisAngle=CFrame.fromAxisAngle
local atan,atan2=math.atan,math.atan2
local acos=math.acos

local function toAxisAngleFromVector(v)
	local z=v.z
	return z*z<0.99999 and v3(v.y,-v.x,0).unit*acos(-z) or v3()
end

local function AxisAngleLookOrientation(c,v,t)--CFrame,Vector,Tween
	local c=c-c.p
	local rv=(inverse(c)*v).unit
	local rz=rv.z
	return rz*rz<0.99999 and c*fromAxisAngle(v3(rv.y,-rv.x,0),acos(-rz)*(t or 1)) or c
end

local function AxisAngleLookNew(v,t)--CFrame,Vector,Tween
	local rv=v.unit
	local rz=rv.z
	return rz*rz<0.99999 and fromAxisAngle(v3(rv.y,-rv.x,0),acos(-rz)*(t or 1)) or cf()
end

local function AxisAngleLook(c,v,t)--CFrame,Vector,Tween
	local rv=(inverse(c)*v).unit
	local rz=rv.z
	return rz*rz<0.99999 and c*fromAxisAngle(v3(rv.y,-rv.x,0),acos(-rz)*(t or 1)) or c
end




local Sensitivity=0.005


local CameraDirection=Vector3.new(0,0,1)

local function EulerAnglesYX(l)
	local x,z=l.x,l.z
	return atan(l.y/(x*x+z*z)^0.5),-atan2(x,-z)
end

local function AnglesXY(l)
	local z=l.z
	return atan2(l.y,-z),-atan2(l.x,-z)
end

local function MouseMoved(Input)
	if Input.UserInputType==Enum.UserInputType.MouseMovement then
		local dx,dy=Input.Delta.x*Sensitivity,Input.Delta.y*Sensitivity
		local m2=dx*dx+dy*dy
		if m2>0 then
			CameraDirection=(AxisAngleLookOrientation(RootPart.CFrame,CameraDirection)*fromAxisAngle(v3(-dy,-dx,0),m2^0.5)).lookVector
		end
		local RootOrientation=RootPart.CFrame-RootPart.Position
		local RelativeDirection=RootOrientation:inverse()*CameraDirection
		local AngX,AngY=AnglesXY(RelativeDirection)--RootOrientation:inverse()*
		if AngX<-1.57*11/12 then
			local y,z,c,s=RelativeDirection.y,RelativeDirection.z,math.cos(-1.57*11/12-AngX),-math.sin(-1.57*11/12-AngX)
			z,y=z*c-y*s,z*s+y*c
			CameraDirection=RootOrientation*v3(RelativeDirection.x<0 and -(1-y*y-z*z)^0.5 or (1-y*y-z*z)^0.5,y,z)
		elseif AngX>1.57*11/12 then
			local y,z,c,s=RelativeDirection.y,RelativeDirection.z,math.cos(1.57*11/12-AngX),-math.sin(1.57*11/12-AngX)
			z,y=z*c-y*s,z*s+y*c
			CameraDirection=RootOrientation*v3(RelativeDirection.x<0 and -(1-y*y-z*z)^0.5 or (1-y*y-z*z)^0.5,y,z)
		end
	end
end

local Mouse= Player:GetMouse()

local Zoom=-0.5


InputService.InputChanged:connect(MouseMoved)

Neck.C1=cf()

local _
local DirectionBound=3.14159/3
local CurrentAngY=0

local function CameraUpdate()
	Camera.CameraType="Scriptable"
	local cx,cz=CameraDirection.x,CameraDirection.z
	local rvx,rvz=RootPart.Velocity.x,RootPart.Velocity.z
	if rvx*rvx+rvz*rvz>4 and cx*rvx+cz*rvz<-0.5*(cx*cx+cz*cz)^0.5*(rvx*rvx+rvz*rvz)^0.5 then
		DirectionBound=math.min(DirectionBound*0.9,math.abs(CurrentAngY*0.9))
	else
		DirectionBound=DirectionBound*0.1+3.14159/3*0.9
	end
	local AngX,AngY=EulerAnglesYX((RootPart.CFrame-RootPart.Position):inverse()*CameraDirection)
	if AngY>DirectionBound then
		RootPart.CFrame=RootPart.CFrame*CFrame.Angles(0,AngY-DirectionBound,0)
	elseif AngY<-DirectionBound then
		RootPart.CFrame=RootPart.CFrame*CFrame.Angles(0,AngY+DirectionBound,0)
	end
	_,CurrentAngY=EulerAnglesYX((RootPart.CFrame-RootPart.Position):inverse()*CameraDirection)
	local CameraOrientation=AxisAngleLookNew((RootPart.CFrame-RootPart.Position):inverse()*CameraDirection,1)
	Neck.C0=CFrame.new(0,1,0)*CameraOrientation*CFrame.new(0,0.5,0)
	local PreCam=AxisAngleLook(RootPart.CFrame*cf(0,1,0),RootPart.CFrame*v3(0,1,0)+CameraDirection)*CFrame.new(0,0.825,0)
	if Zoom==8 then
		local Part,Position=workspace:findPartOnRay(Ray.new(PreCam.p,PreCam.lookVector*-8),Character)
		Camera.CoordinateFrame=PreCam*CFrame.new(0,0,(Position-PreCam.p).magnitude)
	else
		Camera.CoordinateFrame=PreCam*CFrame.new(0,0,Zoom)
	end
end

game:GetService("RunService").RenderStepped:connect(CameraUpdate)

TogglePerson

local person = 1
local userInputService = game:GetService("UserInputService")
local character = script.Parent.Parent
local player = game.Players.LocalPlayer
local tweenService = game:GetService("TweenService")
local tInfo = TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0)
local tThird = tweenService:Create(character:WaitForChild("Humanoid"), tInfo, {CameraOffset = Vector3.new(3, 0, 0)})
local cameraZoomThird = 7.5
local camera = workspace.CurrentCamera

function onToggle()
	if person == 1 then
		script.Parent.Disabled = false
		script.ChangeVal:FireServer(player.ShiftLock, false)
		character.HideHead.Disabled = false
		character.LockMouse.Disabled = true
		character.LockMouse.Disabled = false
		--player.CameraMinZoomDistance = 0.5
		--player.CameraMaxZoomDistance = 0.5
	elseif person == 3 then
		script.Parent.Disabled = true
		script.ChangeVal:FireServer(player.ShiftLock, true)
		character.HideHead.Disabled = true
		for _, hat in pairs(character:GetChildren()) do
			if hat:IsA("Accessory") or hat:IsA("Hat") then
				hat:FindFirstChildWhichIsA("BasePart").LocalTransparencyModifier = 0
			end
		end
		for index, part in pairs(character:GetChildren()) do
			if part:IsA("BasePart") and part.Name ~= "HumanoidRootPart" then
				part.LocalTransparencyModifier = 0
			end
		end
		camera.CameraType = Enum.CameraType.Custom
		player.CameraMaxZoomDistance = cameraZoomThird
		player.CameraMinZoomDistance = cameraZoomThird
		tThird:Play()
	end
end

userInputService.InputBegan:Connect(function(input, gameProcessing)
	if not gameProcessing then
		if input.KeyCode == Enum.KeyCode.Q then
			if person == 1 then
				person = 3
			else
				person = 1
			end
			onToggle()
		end
	end
end)

Server

script.Parent.ChangeVal.OnServerEvent:Connect(function(player, valIns, val)
	valIns.Value = val
end)

So if the issue is that the head movement isn’t that smooth well, it could be because using CFrame lookat methods on the player’s character is not that smooth usually. It’s better to use something like bodygyros or alignorientation, much smoother.

2 Likes

a little update i moved it around it all works properly i just cant look around after i start moving!

1 Like

to be honest im not quite sure how that could be a issue though because it was working perfectly beforehand!

1 Like

Oh, that’s strange then? Whenever I tried to use methods of head movement they were jittery without constraints like bodygyros or align orientation haha.

2 Likes

Um what is Head? Are you sure it actually exists? It could be because of the movement you made that as soon as you move it sorta flings itself out or something.

2 Likes

now that you mention it im not entirely sure… should i have it look in the players tab?

1 Like

Yeah possibly. Maybe add a waitforchild actually if your code is running on the client, pretty sure it is due to the renderstepped.

By waitforchild I mean you know, :WaitForChild(“Head”). I think you know waht I mean.

2 Likes

i sort of understand my friend has been teaching me code im still id say decently new to it but this is one of the most advanced thing ive done

1 Like

Oh alright, yeah basically waitforchild will basically yield the script until it finds the child of what you inserted. So it’s less likely for you to run into an error where something doesn’t exist yet. People use waitforchild alot on the client because sometimes things haven’t loaded in yet. As alot of the stuff from the server is replicated to the client.

Yield is just a fancy way of saying like pause. It just pauses the script at the line where you called waitforchild and doesn’t go any lower than that until it finds the child.

2 Likes

i added it and it works a little more responsive but i dont think it actually move the head and it also stops when i click onto the screen to move around heres a link to a clip i took of it script - Clipped with Medal.tv

1 Like