Need help with torso and head following mouse

It doesn’t, it contains the waist motor6d which the torso doesn’t contain.

Can you please, in depth, explain how the code works? I know some basics of coding, but I don’t know globals (such as workspace) in your code, or what the Neck and Waist C0 lerp is doing. Since there are no YouTube tutorials on this topic (that I know of), and I need to ask you so I can understand how to make the character move that smoothly.

3 Likes

Would this go inside a LocalScript in StaryerPlayerScripts?

3 Likes

Yeah this is Client-Sided code, you’ll need to place it in LocalScript and you need to place it in StarterCharacterScripts.

2 Likes

How could I possibly make this server-sided?

1 Like

Hey! How are you doing? I was looking at the script given by @CleverSource and I noticed your reply. I also needed to make the event server-sided and after playing around a bit, I got the way to make the script server-sided. So, let me explain you how to make the script server-sided.

What you'll have to do:

  1. Make two RemoteEvents via the server-script. - One for getting the client's player and the other for getting the client-sided function. Ensure that the Parents and Names of the RemoteEvents are correctly declared.
  2. Declare the constant data in the server-script. - Create empty variables for the purpose.
  3. Go to the LocalScript and WaitFor the RemoteEvents.
  4. Declare the client data on the local script. - This is the data that the server-script cannot handle. Fire the client's player-yielding RemoteEvent. - The alternate way to do this is to use
    game:GetService("Players").PlayerAdded:Connect(function(player) --[[The content of the script]]-- end)
    
  5. Assign the values of the constant data declared above.
  6. Declare the variable values inside the client-sided function script. - This is done because this data is the main doer of the function.
  7. Fire the client-sided function script. - Here, I've used
    game:GetService("RunService").RenderStepped:(function() --[[Firing the Server]]-- end)
    
    • RunService cannot be fired on server-script.
  8. Call the function shown by @CleverSource inside the OnServerEvent connection.

And then you have it! you have successfully server-sided the script. For reference, I’ll add in the LocalScript and the Script.
Note: Some of the variables and constants have been removed from @CleverSource’s code, as that data was unused.

Local Script:

---------------------------------------------------------------------
local GetLocalData = game:GetService("ReplicatedStorage"):WaitForChild("GetLocalData")
local GetMouseFollowFunction = game:GetService("ReplicatedStorage"):WaitForChild("GetMouseFollowFunction")
--(iii)
---------------------------------------------------------------------
local CameraSubject = workspace.CurrentCamera.CameraSubject -- (iv)

GetLocalData:FireServer()-- (v)


RunService.RenderStepped:Connect(function()
	local PlayerMouseHit = game.Players.LocalPlayer:GetMouse().Hit.p -- (vii)
	GetMouseFollowFunction:FireServer(CameraSubject,PlayerMouseHit) -- (viii)
end)

Note: This is to be put in StarterCharacterScripts.

Server Script:

local GetLocalData = Instance.new("RemoteEvent")
local GetMouseFollowFunction = Instance.new("RemoteEvent")

GetLocalData.Name = "GetLocalData"
GetLocalData.Parent = game:GetService("ReplicatedStorage")

GetMouseFollowFunction.Name = "GetMouseFollowFunction"
GetMouseFollowFunction.Parent = game:GetService("ReplicatedStorage")
-- (i)
---------------------------------------------------------------------

local Character
local Head
local Neck

local Torso
local Waist

local WaistOriginC0
local NeckOriginC0

-- (ii)
---------------------------------------------------------------------

GetLocalData.OnServerEvent:Connect(function(Player)

	Character = Player.Character or Player.CharacterAdded:Wait()
	Head = Character:WaitForChild("Head")
	Neck = Head:WaitForChild("Neck")

	Torso = Character:WaitForChild("UpperTorso")
	Waist = Torso:WaitForChild("Waist")
	
	WaistOriginC0 = Waist.C0
	NeckOriginC0 = Neck.C0
	
	Neck.MaxVelocity = 1/3
end)
-- (vi) 
---------------------------------------------------------------------


GetMouseFollowFunction.OnServerEvent:Connect(function(_,CameraSubject,PlayerMouseHit)
	if Character:FindFirstChild("UpperTorso") and Character:FindFirstChild("Head") then
		local TorsoLookVector = Torso.CFrame.lookVector
		local HeadPosition = Head.CFrame.p

		if Neck and Waist then
			if CameraSubject:IsDescendantOf(Character) or CameraSubject:IsDescendantOf(Player) then
				local Point = PlayerMouseHit

				local Distance = (Head.CFrame.p - Point).magnitude
				local Difference = Head.CFrame.Y - Point.Y

				Neck.C0 = Neck.C0:lerp(NeckOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 0.5), (((HeadPosition - Point).Unit):Cross(TorsoLookVector)).Y * 1, 0), 0.5 / 2)
				Waist.C0 = Waist.C0:lerp(WaistOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 0.5), (((HeadPosition - Point).Unit):Cross(TorsoLookVector)).Y * 0.5, 0), 0.5 / 2)
			end
		end
	end	
end)

-- (ix)
---------------------------------------------------------------------

Thanks for reading. If this helps, kindly leave a like.

41 Likes

How would i do this for arms, on the y axis only?

Hm, something in the script is giving me this error, I truly appreciate your assistance and help!
image

3 Likes

It says that your Remote Event is not invoking. Can you show me the server script that you are using?

1 Like
local GetLocalData = Instance.new("RemoteEvent")
local GetMouseFollowFunction = Instance.new("RemoteEvent")

GetLocalData.Name = "GetLocalData"
GetLocalData.Parent = game:GetService("ReplicatedStorage"):WaitForChild("General")

GetMouseFollowFunction.Name = "GetMouseFollowFunction"
GetMouseFollowFunction.Parent = game:GetService("ReplicatedStorage"):WaitForChild("General")
-- (i)
---------------------------------------------------------------------

local Character
local Head
local Neck

local Torso
local Waist

local WaistOriginC0
local NeckOriginC0

-- (ii)
---------------------------------------------------------------------

GetLocalData.OnServerEvent:Connect(function(Player)

	Character = Player.Character or Player.CharacterAdded:Wait()
	Head = Character:WaitForChild("Head")
	Neck = Head:WaitForChild("Neck")

	Torso = Character:WaitForChild("UpperTorso")
	Waist = Torso:WaitForChild("Waist")

	WaistOriginC0 = Waist.C0
	NeckOriginC0 = Neck.C0

	Neck.MaxVelocity = 1/3
end)
-- (vi) 
---------------------------------------------------------------------


GetMouseFollowFunction.OnServerEvent:Connect(function(_,CameraSubject,PlayerMouseHit)
	if Character:FindFirstChild("UpperTorso") and Character:FindFirstChild("Head") then
		local TorsoLookVector = Torso.CFrame.lookVector
		local HeadPosition = Head.CFrame.p

		if Neck and Waist then
			if CameraSubject:IsDescendantOf(Character) or CameraSubject:IsDescendantOf(Player) then
				local Point = PlayerMouseHit

				local Distance = (Head.CFrame.p - Point).magnitude
				local Difference = Head.CFrame.Y - Point.Y

				Neck.C0 = Neck.C0:lerp(NeckOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 0.5), (((HeadPosition - Point).Unit):Cross(TorsoLookVector)).Y * 1, 0), 0.5 / 2)
				Waist.C0 = Waist.C0:lerp(WaistOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 0.5), (((HeadPosition - Point).Unit):Cross(TorsoLookVector)).Y * 0.5, 0), 0.5 / 2)
			end
		end
	end	
end)

-- (ix)
---------------------------------------------------------------------
1 Like

I changed up the RemoteEvent since it’s in ReplicatedStorage inside of a folder named “General”.

1 Like

The error shown in the picture does not show up im my device. Kindly check for any syntax errors.

1 Like

Oh wait, I created 2 RemoteEvents in the RS in a folder and created 2 extra ones in the script. That’s probably why.

1 Like

And now it’s spamming this error:


Referencing line 49:

if CameraSubject:IsDescendantOf(Character) or CameraSubject:IsDescendantOf(Player)
1 Like

Can you tell me the value of the CameraSubject?

Not sure how to find it, but also forgot to note that Player is underlined red in the code.

You can try adding a constant for player, then getting the value in the getLocalData function . See if that helps. But the error shows CameraSubject is missing so you will have to get that.

Is this what you’re looking for? In that case, it’s humanoid. image

Can you try adding print(CameraSubject) after local HeadPosition? I’ll get a better understanding of the issue if I see whether the CameraSubject is firing.

image
This is what it prints.