How can I make the waist and the head follow the camera?

So… I’ve been searching for a solution for this for a long time. And I’ve found some. I have one that works, but other players cannot see it. I want to achieve something a head/waist movement in mad city:

I have a script though, this is a script that works, but players cannot see other players moving their head… Credits for the script go to WesFluff.
Script:

wait()


local Ang = CFrame.Angles	
local aSin = math.asin
local aTan = math.atan



local Cam = game.Workspace.CurrentCamera

local Plr = game.Players.LocalPlayer
local Mouse = Plr:GetMouse()
local Body = Plr.Character or Plr.CharacterAdded:wait()
local Head = Body:WaitForChild("Head")
local Hum = Body:WaitForChild("Humanoid")
local Core = Body:WaitForChild("HumanoidRootPart")
local IsR6 = (Hum.RigType.Value==0)	
local Trso = (IsR6 and Body:WaitForChild("Torso")) or Body:WaitForChild("UpperTorso")
local Neck = (IsR6 and Trso:WaitForChild("Neck")) or Head:WaitForChild("Neck")	
local Waist = (not IsR6 and Trso:WaitForChild("Waist"))	


local MseGuide = false


local TurnCharacterToMouse = false


local HeadHorFactor = 1
local HeadVertFactor = 0.6
local BodyHorFactor = 0.5
local BodyVertFactor = 0.4


local UpdateSpeed = 0.5

local NeckOrgnC0 = Neck.C0	
local WaistOrgnC0 = (not IsR6 and Waist.C0)	



Neck.MaxVelocity = 1/3

if TurnCharacterToMouse == true then
	MseGuide = true
	HeadHorFactor = 0
	BodyHorFactor = 0
end

game:GetService("RunService").RenderStepped:Connect(function()
	local CamCF = Cam.CoordinateFrame
	if ((IsR6 and Body["Torso"]) or Body["UpperTorso"])~=nil and Body["Head"]~=nil then	
		local TrsoLV = Trso.CFrame.lookVector
		local HdPos = Head.CFrame.p
		if IsR6 and Neck or Neck and Waist then	--[Make sure the Neck still exists.]
			if Cam.CameraSubject:IsDescendantOf(Body) or Cam.CameraSubject:IsDescendantOf(Plr) then
				local Dist = nil;
				local Diff = nil;
				if not MseGuide then	
					Dist = (Head.CFrame.p-CamCF.p).magnitude
					Diff = Head.CFrame.Y-CamCF.Y
					if not IsR6 then	
						Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang((aSin(Diff/Dist)*HeadVertFactor), -(((HdPos-CamCF.p).Unit):Cross(TrsoLV)).Y*HeadHorFactor, 0), UpdateSpeed/2)
						Waist.C0 = Waist.C0:lerp(WaistOrgnC0*Ang((aSin(Diff/Dist)*BodyVertFactor), -(((HdPos-CamCF.p).Unit):Cross(TrsoLV)).Y*BodyHorFactor, 0), UpdateSpeed/2)
					else	
						Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang(-(aSin(Diff/Dist)*HeadVertFactor), 0, -(((HdPos-CamCF.p).Unit):Cross(TrsoLV)).Y*HeadHorFactor),UpdateSpeed/2)
					end
				else
					local Point = Mouse.Hit.p
					Dist = (Head.CFrame.p-Point).magnitude
					Diff = Head.CFrame.Y-Point.Y
					if not IsR6 then
						Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang(-(aTan(Diff/Dist)*HeadVertFactor), (((HdPos-Point).Unit):Cross(TrsoLV)).Y*HeadHorFactor, 0), UpdateSpeed/2)
						Waist.C0 = Waist.C0:lerp(WaistOrgnC0*Ang(-(aTan(Diff/Dist)*BodyVertFactor), (((HdPos-Point).Unit):Cross(TrsoLV)).Y*BodyHorFactor, 0), UpdateSpeed/2)
					else
						Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang((aTan(Diff/Dist)*HeadVertFactor), 0, (((HdPos-Point).Unit):Cross(TrsoLV)).Y*HeadHorFactor), UpdateSpeed/2)
					end
				end
			end
		end
	end
	if TurnCharacterToMouse == true then
		Hum.AutoRotate = false
		Core.CFrame = Core.CFrame:lerp(CFrame.new(Core.Position, Vector3.new(Mouse.Hit.p.x, Core.Position.Y, Mouse.Hit.p.z)), UpdateSpeed / 2)
	else
		Hum.AutoRotate = true
	end
end)
6 Likes

I remember using that script myself. I got it from the toolbox. The issue is it is all done from a local script. You may want to use a remote event to update the rotation on server.

2 Likes

Oof forgot to credit the owner. Anyway, do I keep the script and add a remote event?

If you want. It would not be prudent to update every render frame, I believe updating every 1/10th of a second would be better since it’s less strain on the server.

I apologize for the bump, but I’ve stumbled across some useful code that would help solve this.

Solution

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 camera_angle = math.atan2(camera.CFrame.LookVector.X, camera.CFrame.LookVector.Z)
				local body_angle = math.atan2(body.CFrame.LookVector.X, body.CFrame.LookVector.Z)
				local theta2 = (camera_angle-body_angle)%(2*math.pi)
				
				if theta2 > math.pi/2 and theta2 < math.pi*1.5 then
					theta2 = math.pi-theta2
				end
				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);
6 Likes

Is there a way to toggle this on and off. I have tried and ended up with this!
image|354x417

Don’t worry. I found it!
If you want I can share it if anyone needs it!

1 Like

Hello! where did you find this script?

This is because you’re running the script on the client, you would have to make a separate server script and use a remote event.

1 Like