Head face camera script needing to be global and not local

Hello! I am new to scripting, and I have this script inside of StarterGui that makes the torso and head face the camera’s position. It works for the player itself, but if you were to look at somebody else, their torso and head stays normal, because it’s local and not global. (Keep in mind the script below doesn’t belong to me, I don’t know it’s true owner)

Here’s the script:



local Ang = CFrame.Angles	--[Storing these as variables so I dont have to type them out.]
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)	--[Checking if the player is using R15 or R6.]
local Trso = (IsR6 and Body:WaitForChild("Torso")) or Body:WaitForChild("UpperTorso")
local Neck = (IsR6 and Trso:WaitForChild("Neck")) or Head:WaitForChild("Neck")	--[Once we know the Rig, we know what to find.]
local Waist = (not IsR6 and Trso:WaitForChild("Waist"))	--[R6 doesn't have a waist joint, unfortunately.]

	[Whether rotation follows the camera or the mouse.]
	[Useful with tools if true, but camera tracking runs smoother.]

local MseGuide = false
	[Whether the whole character turns to face the mouse.]
	[If set to true, MseGuide will be set to true and both HeadHorFactor and BodyHorFactor will be set to 0]
local TurnCharacterToMouse = false
	[Horizontal and Vertical limits for head and body tracking.]
	[Setting to 0 negates tracking, setting to 1 is normal tracking, and setting to anything higher than 1 goes past real life head/body rotation capabilities.]
local HeadHorFactor = 1
local HeadVertFactor = 0.6
local BodyHorFactor = 0.125
local BodyVertFactor = 0.125

	[How fast the body rotates.]
	[Setting to 0 negates tracking, and setting to 1 is instant rotation. 0.5 is a nice in-between that works with MseGuide on or off.]
	[Setting this any higher than 1 causes weird glitchy shaking occasionally.]
local UpdateSpeed = 0.15

local NeckOrgnC0 = Neck.C0	--[Get the base C0 to manipulate off of.]
local WaistOrgnC0 = (not IsR6 and Waist.C0)	--[Get the base C0 to manipulate off of.]


Neck.MaxVelocity = 1/3

-- Activation]:
if TurnCharacterToMouse == true then
	MseGuide = true
	HeadHorFactor = 0
	BodyHorFactor = 0

	local CamCF = Cam.CoordinateFrame
	if ((IsR6 and Body["Torso"]) or Body["UpperTorso"])~=nil and Body["Head"]~=nil then	--[Check for the Torso and Head...]
		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	--[If not tracking the Mouse then get the Camera.]
					Dist = (Head.CFrame.p-CamCF.p).magnitude
					Diff = Head.CFrame.Y-CamCF.Y
					if not IsR6 then	--[R6 and R15 Neck rotation C0s are different; R15: X axis inverted and Z is now the Y.]
						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	--[R15s actually have the properly oriented Neck CFrame.]
						Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang(-(aSin(Diff/Dist)*HeadVertFactor), 0, -(((HdPos-CamCF.p).Unit):Cross(TrsoLV)).Y*HeadHorFactor),UpdateSpeed/2)
					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)
						Neck.C0 = Neck.C0:lerp(NeckOrgnC0*Ang((aTan(Diff/Dist)*HeadVertFactor), 0, (((HdPos-Point).Unit):Cross(TrsoLV)).Y*HeadHorFactor), UpdateSpeed/2)
	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)
		Hum.AutoRotate = true

How would I make it display for other players and not just for the player them self? (Where do I put the script, and if needed, what (hopefully small) changes need to be made to the script itself?)

Sorry for not knowing myself, I’m new to scripting and I just need this task done, which should be simple if you know what you’re doing, so please guide me through it D:


You’ll need to utilize RemoteEvents here to replicate this change to the server.

However, I wouldn’t advise calling :FireServer on the remote every frame, like in your client code here. I would suggest leaving your code as-is, however, you could implement a timer system in your RenderStep function that fires the server event of the RemoteEvent every .2 seconds or so. When you fire the remote, pass in the CFrames for your neck and waist C0s so the server knows what to set. In your .OnServerEvent connection on the server, have it so it calls the :FireAllClients() method passing in the same parameters. From there, you can implement a .OnClientEvent in your client code to check and see if the player is not the client itself, and if so, set that player’s neck and waist C0s to the parameters passed through.

Apologies if this is wordy or hard to understand, I’m not a great writer. :joy:

This is in a nutshell, of course. If you need further clarification let me know! Hope this helps. :slight_smile:

1 Like

It’s absolutely fine :slight_smile:

I will try researching about the terms used here, thanks for the help, it’s a bit overwhelming for a noob like me, but I’ll try :stuck_out_tongue: I get what the parts will do, just not how to do them

1 Like