Server Side Mouse Following? Choppy character momement

I’m using a mouse following script made by @CleverSource and I was able to make it work on a server script, but it’s very choppy. I’m using remote events to send everything to the server. I need it to be server sided because want other players to see where they’re looking.
Both recordings should be
Local Script:


Server Script:

  1. Here’s the code for the server script video:
    Local
-- 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/5
remote = game.Workspace:WaitForChild("remote:"..Player.Name)
PlayerMouse.Move:Connect(function()
	local CameraCFrame = Camera.CoordinateFrame

	if Character["UpperTorso"] and Character["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
				nserver = Neck.C0:lerp(NeckOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 0.5), (((HeadPosition - Point).Unit):Cross(TorsoLookVector)).Y * 1, 0), 0.5 / 2)
				wserver = Waist.C0:lerp(WaistOriginC0 * CFrame.Angles(-(math.atan(Difference / Distance) * 0.5), (((HeadPosition - Point).Unit):Cross(TorsoLookVector)).Y * 0.5, 0), 0.5 / 2)
				remote:FireServer(nserver,wserver, Player)
			end
		end
	end	
end)

Server:

--game.Players.PlayerAdded:Connect(function(plr)
	gui = game.ReplicatedStorage.BillboardGui
	game.ReplicatedStorage.ClickDetector:Clone().Parent = game.Workspace:WaitForChild(plr.Name).HumanoidRootPart
	gui:Clone().Parent = game.Workspace:WaitForChild(plr.Name).Head
	remote = game.Workspace:WaitForChild("remote:"..plr.Name)
	remote.OnServerEvent:Connect(function(nserver,wserver,Player)
			if game.Workspace[plr.Name].Humanoid.Health ~= 0 then
				remote:Disconnect()
				game.Workspace[plr.Name].Head.Neck.C0 = wserver
				game.Workspace[plr.Name].UpperTorso.Waist.C0 = Player
			end
	end)
	remote = game.Workspace:WaitForChild("remote:"..plr.Name).OnServerEvent:Connect(remote)
end)
game.Players.PlayerRemoving:Connect(function(plr)
	if game.Workspace["remote:"..plr.Name] then
		game.Workspace["remote:"..plr.Name]:Destroy()
	else
	end
end)

Here’s the code for the local script video
Local:

--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/5
remote = game.Workspace:WaitForChild("remote:"..Player.Name)
PlayerMouse.Move:Connect(function()
	local CameraCFrame = Camera.CoordinateFrame

	if Character["UpperTorso"] and Character["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)

I think it’s because of latency between the server and the client or because I’m using remote events.
Is there a better way to do this or a way to make it less choppy?

Thank you!

3 Likes

You can use FireAllClients for other players can see your change

That aint what he was asking for help on :skull:
Anyway, if hes still active, it is because ping, i think. As far as i know theres nothing you can do about it.

Edit: The one thing about the FireAllClients is that it might be smoother.

You should do the mouse following on a local script, as character control is already replicated to the server.