Pet Movement Lags when going away from origin point

  1. What do you want to achieve? A simple pet following system

  2. What is the issue?
    while close to the center of the map, there is no issues, however when moving towards the end of the baseplate it starts becoming very choppy and I can’t figure out why. I’ll ammend this post with a video when I can.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I have tried changing the loops, but to no avail, I’ve tried unanchoring my pet, but that just broke everything, I’m a relatively new scripter so I’m at a loss for what I could’ve done wrong (Other than probably being super innefficient)

Local Script in StarterPlayerScripts


local runService = game:GetService("RunService")
local playerPets = workspace:WaitForChild("Player_Pets")
local circle = math.pi * 2
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local character = player.Character
if player.Character == nil then
	player.CharacterAdded:Wait()
	local character = player.Character
end

local folder = Instance.new("Folder")
folder.Name = game.Players.LocalPlayer.Name
folder.Parent = workspace:WaitForChild("Player_Pets")
wait(2)
local function getPosition(angle, radius)
	local x = math.cos(angle) * radius
	local z = math.sin(angle) * radius
	return x, z
end
local Paramas = RaycastParams.new()
Paramas.FilterDescendantsInstances = {game.Workspace.Player_Pets:GetDescendants(), game.Workspace:WaitForChild(player.Name)}
Paramas.FilterType = Enum.RaycastFilterType.Exclude
Paramas.IgnoreWater = true;
function GetY(pos, size)
	if workspace:Raycast(pos + Vector3.new(0,15,0),Vector3.new(0,-100,0),Paramas) then
		return (workspace:Raycast(pos + Vector3.new(0,15,0),Vector3.new(0,-100,0),Paramas).Position.Y - player.Character:WaitForChild("HumanoidRootPart").Position.Y) + size.Y
	else
		return character.PrimaryPart.Position.Y
	end
end
local function positionPets(character, folder)
	for i, pet in pairs(folder:GetChildren()) do
		local radius = 5
		local angle = i + (circle / #folder:GetChildren())
		local x, z = getPosition(angle, radius)
		local sin = (math.sin(15 * time() + 1.6)/.5)+1
		local cos = math.cos(7 * time() + 1)/4
		local offsetY = -  character.PrimaryPart.Position.Y

		local petData = require(game.ReplicatedStorage:FindFirstChild("PetModels"):FindFirstChild(pet.Name):FindFirstChild("petData"))

		local function lerpCharacter(moving)
			if petData["flys"] == false then
				if moving then
					pet.PrimaryPart.CFrame = pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, GetY(pet.PrimaryPart.Position, pet.PrimaryPart.Size)+sin+1.5, z), 0.1)	
				else
					pet.PrimaryPart.CFrame = pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, GetY(pet.PrimaryPart.Position, pet.PrimaryPart.Size)+2, z), 0.1)
				end
			else
				pet.PrimaryPart.CFrame = pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, GetY(pet.PrimaryPart.Position)/2+math.sin(time()*3)+1, z), 0.1)
			end 
		end

		if character.Humanoid.MoveDirection.Magnitude > 0 then
			lerpCharacter(true)
		else
			lerpCharacter(false)
		end
	end
end
game:GetService("RunService").Heartbeat:Connect(function()
	for _, PlrFolder in pairs(playerPets:GetChildren()) do
		local Player = game.Players:FindFirstChild(PlrFolder.Name) or nil
		if Player ~= nil then
			local character = Player.Character or nil
			if character ~= nil then
				positionPets(character, PlrFolder)
			end
		end
	end
end)

local function createFolder()
	if not workspace:WaitForChild("Player_Pets"):WaitForChild(Players.LocalPlayer.Name) then
		local newFolder = Instance.new("Folder", workspace:WaitForChild("Player_Pets"))
		newFolder.Name = Players.LocalPlayer.Name
	end
end

game:GetService("UserInputService").InputBegan:Connect(function(input, GameProcessed)
	if GameProcessed then
		return
	end
	if input.KeyCode==Enum.KeyCode.X then
		local pet = game.ReplicatedStorage.PetModels:WaitForChild("PetTest"):Clone()
		createFolder()
		pet.Parent = workspace:WaitForChild("Player_Pets"):WaitForChild(Players.LocalPlayer.Name)
	end
end)

script in server script service

local Players = game:GetService("Players")
local PlayerPets = game.Workspace.Player_Pets

local function PlayerAdded(player)
	local folder = Instance.new("Folder")
	folder.Name = player.Name
	folder.Parent = PlayerPets
end

local function PlayerRemoving(player)
	local folder = PlayerPets:FindFirstChild(player.Name)
	if folder == nil then return end
	folder:Destroy()
end

for _, player in Players:GetChildren() do 
	task.spawn(function()
		PlayerAdded(player)
	end)
end

Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(PlayerRemoving)

Thanks in advance!!

1 Like

Tried messing around a bit more and still nothing, I’m super confused.

still having this issue D: any help is very appreciated

bumping since I’m still having this issue and the one scripter I do know is ghosting me :melting_face:

I think this is because you are lerping the character, lerps are cool and all but they aren’t the smoothest. I’ve seen many people have issues with lerping.

Why don’t you just use humanoid:MoveTo()

Many games use :MoveTo() on their NPCs and their movement is quite smooth.

Also try using basepart:SetNetworkOwner(nil) which would give ownership of the pet to the server instead of the client. You can also try the other way round if you want.

Setting network ownership can make movement smoother.

Really? I heard that moveto was the unoptimised method. Eitherwho, forgive me if i’m wrong, it’s very late here, but my pet models don’t have humanoids in them, so I don’t think this method would work for me without breaking alot of other things. i’ll try to get back to you later when i have a bit more of a functioning brain, thanks.

Edit: and if i’m not wrong, doesn’t moveto have that annoying 7ish second timeout?

Edit 2: SetNetworkOwner cant be run from localscripts, which is what the pets script is.

Okay now I’m confused, I added a task.wait() into the heartbeat loop and now it lags when close but is smooth when far??? why doesnt roblox just want me to meet in the middleeeee

This is a common misconception.

You can just add them using the plus icon, as long as you have the model rigged properly with motor6ds and what not it should work.

I don’t think so

Use remote events.

Tried that but my pet is moving towards the player VERY VERY slowly and then sometimes walks too far and then turns around and walks back for some reason? other than the chopiness lerping has given me the best results so far… ;v;

I seem to get okay results by using Model:MoveTo. will test further and update this post if needed

Might be due to other things such as the pet’s mass.