Need help with torso and head following mouse

I’ve been working on a script where Arms, torso, and the characters head follows the mouse

The issue I am experiencing is that the script i have already moves the whole character.

local plr = game:GetService("Players").LocalPlayer

game:GetService("RunService").RenderStepped:connect(function()
	if plr.Character then
		local root = plr.Character.HumanoidRootPart
		if root then
			root.CFrame = CFrame.new(root.CFrame.p,root.CFrame.p+Vector3.new(cam.CFrame.lookVector.X,0,cam.CFrame.lookVector.Z))
		end
	end
end)

i’ve tried messing with humanoid parts and what exactly it needs to move, but so far hasn’t done anything for me.

Can someone tell me what i’m doing wrong.

36 Likes

Can you clarify what you mean? Do you want the player’s head & torso to follow the mouse or the camera?

5 Likes

Like when you move your mouse up and down the character doesn’t move but what i want it to do is the torso and head to go up and down with the mouse, does that help?

1 Like

Also, helpful tip;

Make sure to use the code block feature, as it is really hard to read your code.
image

3 Likes

thank you for the tip i’m new so that helps a lot!

3 Likes

I have made a simple local script for you which makes the player’s head and torso follow the player’s mouse. I’ll have a working example below, the .rbxl file provided, and the code! I hope this helps. If you have any questions feel free to ask me.

Code:

local RunService = game:GetService("RunService")

local Player = game.Players.LocalPlayer
local PlayerMouse = Player:GetMouse()

local Camera = workspace.CurrentCamera

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

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

local Humanoid = Character:WaitForChild("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")

local NeckOriginC0 = Neck.C0
local WaistOriginC0 = Waist.C0

Neck.MaxVelocity = 1/3

RunService.RenderStepped:Connect(function() 
	local CameraCFrame = Camera.CoordinateFrame
	
	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 Camera.CameraSubject:IsDescendantOf(Character) or Camera.CameraSubject:IsDescendantOf(Player) then
				local Point = PlayerMouse.Hit.p
				
				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)

RBXL:
MouseFollowing.rbxl (15.5 KB)

Example: (please note the gif service I use is not in 60 FPS so it looks choppy)
https://gyazo.com/013acb36b08c370baea948cf62bcccc6.gif

214 Likes

Does it work with R6? I would love it if it does!

3 Likes

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.

2 Likes

Would this go inside a LocalScript in StaryerPlayerScripts?

2 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.

47 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

2 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