Pet following system problem

Update pet positions on both server and client.

  1. The problem I’m facing is that when I update the position of pets on the client, everything works correctly. However, when I try to update the position of pets in a regular script through a remote event so that their position is also visible on the server, an error occurs, and the pet positions lag behind a bit. I tried using AlignPosition and AlignOrientation , but I couldn’t find a solution. They only seem to make it worse because when I update the position from the server, the vector force is too strong for very small distances. My goal is very simple but challenging for me to achieve: to make the pet positions look the same on the client and the server so that other players can see the pet positions

Tried solutions:

  1. Using alignOrientation and alignPosition in a regular script.
  2. Using remote events to update pet positions in the regular script.
  3. Updating pet positions in a regular script without using remote events or local scripts (i.e., transferring code from a LocalScript to a Script with necessary modifications).

--Here is the localScript code
local RS = game:GetService("RunService")
local players = game:GetService("Players")
local Player = game.Players.LocalPlayer
local petPosRemote = game:GetService("ReplicatedStorage"):WaitForChild("RemotesEvents"):WaitForChild("PetPositionRemote")

local playerPets = game.Workspace:FindFirstChild("PlayerPets")

local circle = math.pi *2
local minimunRadius = 4




local function PositionPets(character, folder)
	for i, pet in folder:GetChildren() do
		local radius = minimunRadius + #folder:GetChildren()
		local angle = i * (circle/ #folder:GetChildren())	
		local yOffset = pet.YOffset.Value
		local x = math.cos(angle) * radius
		local z = math.sin(angle) * radius
		
		local walkSineWave = math.max(math.sin((time() + pet.TimeDelay.Value)* 10) / 2,-0.1)
		local walkFrontBackCos = math.cos((time()+pet.TimeDelay.Value )* 10)/7
		local hoverSineWave =	math.sin((time()+ pet.TimeDelay.Value) * 5) / 10
		local hoverSineWaveIdle = math.sin((time() + pet.TimeDelay.Value)) / 10
		
		local petCFrame = pet.PrimaryPart.CFrame:Lerp(character.HumanoidRootPart.CFrame * CFrame.new(x, yOffset,z),0.1)
		if character.Humanoid.MoveDirection.Magnitude > 0 then
			if pet.Flying == false then
				petCFrame *= CFrame.new(0, walkSineWave, 0) * CFrame.Angles(walkFrontBackCos,0,0)
			else
				petCFrame *= CFrame.new(0,hoverSineWave,0)
			end
		else
			if pet.Flying.Value == true then
				petCFrame *= CFrame.new(0,0.2 + hoverSineWaveIdle, 0)
			end
			
		end
		
		pet:PivotTo(petCFrame)
	end
end

RS.Heartbeat:Connect(function()
	for _, petFolder in playerPets:GetChildren() do
		local character = Player.Character
		repeat wait() until Player.Character
		if not character then return end
		PositionPets(character, petFolder)
		--petPosRemote:FireServer(Player)
	end
end)
1 Like

i don’t know if this could work but suggest create all pets through server-side and use SetNetworkOwner on primaryPart of the pets model

1 Like

It’s true, hahaha! I had thought about it yesterday but had forgotten, thank you for reminding me. I’ll try it now, and I’ll let you know if it worked.

1 Like

ok, now I have this error here, to position the pets I need to have the anchored active, but at the same time, I have to have the anchoring of the primaryPart off to be able to use SetNetworkOwner, how can I do it? I leave the new script that I created .

local petPosRemote = game:GetService(“ReplicatedStorage”):WaitForChild(“RemotesEvents”):WaitForChild(“PetPositionRemote”)
petPosRemote.OnServerEvent:Connect(function(player, petFolder)
for i, pet in petFolder:GetChildren() do
pet.Pet:SetNetworkOwner(player)
end
end)

1 Like

u could unanchored pets and use SetNetworkOwner on PrimaryPart, and for them movement use AlignPosition and AlignOrientation(update them in client-side)

1 Like

Well i made a test with alignposition and alignorientation, (don’t get attention to lags they happens because i doesn’t apply setnetworkowner to them. im really lazy to do it via a remote events and did it through command line)
https://youtu.be/aLsYz8WQMRM (i tried uploud to devforum)

--Here is the localScript code
local RS = game:GetService("RunService")
local players = game:GetService("Players")
local Player = game.Players.LocalPlayer

local character = Player.Character or Player.CharacterAdded:Wait()
local playerPets = game.Workspace:FindFirstChild("PlayerPets")

local circle = math.pi *2
local minimunRadius = 4




local function PositionPets(character, folder)
	local foldertable = folder:GetChildren()
	for i, pet in pairs(foldertable) do
		local radius = minimunRadius + #foldertable
		local angle = i * (circle/ #foldertable)	
		local x = math.cos(angle) * radius
		local z = math.sin(angle) * radius

		local walkSineWave = math.max(math.sin((tick() + pet.TimeDelay.Value)* 10) / 2,-0.1)
		local walkFrontBackCos = math.cos((tick()+pet.TimeDelay.Value )* 10)/7
		local hoverSineWave =	math.sin((tick()+ pet.TimeDelay.Value) * 5) / 10
		local hoverSineWaveIdle = math.sin((tick() + pet.TimeDelay.Value)) / 10

		local petCFrame = character.HumanoidRootPart.CFrame * CFrame.new(x, 5,z)
		if character.Humanoid.MoveDirection.Magnitude > 0 then
			if pet.Flying == false then
				petCFrame *= CFrame.new(0, walkSineWave, 0) * CFrame.Angles(walkFrontBackCos,0,0)
			else
				petCFrame *= CFrame.new(0,hoverSineWave,0)
			end
		else
			if pet.Flying.Value == true then
				petCFrame *= CFrame.new(0,0.2 + hoverSineWaveIdle, 0)
			end
		end

		pet.PrimaryPart.AlignOrientation.CFrame = petCFrame.Rotation
		pet.PrimaryPart.AlignPosition.Position = petCFrame.Position
	end
end

RS.RenderStepped:Connect(function()
	if not character then 
		character = Player.Character 
		return 
	end 
	for _, petFolder in playerPets:GetChildren() do
		PositionPets(character, petFolder)
	end
end)
2 Likes

Hello again, thank you very much, the truth is that now that I see it, you have helped me a lot. Still, I’m having several problems trying to implement the code you provided into my game so that it looks like yours that you showed in the video:
In a new roblox studio model I created the script that you provided me and simplified it so that it works with the properties that I have in the workspace, the first second everything works fine and the parts follow the position of the player, but after 2 seconds it stops They head towards the spawn, I leave the model for you to see and if you know any solution to correct it, so I can implement it in my game. Thank you very much and greetings, sorry for the inconvenience again :slight_smile:
Model 102.rbxl (57.8 KB)

1 Like

as i said before do SetNetworkOwner() on PrimaryPart on every Pet and this problem will disappear
p.s. My question is how are you going to find out later who has these pets and who doesn’t own those pet?
Model 102.rbxl (59.1 KB)

1 Like

Hello again, sorry for the wait hahaha, thank you very much again for your help. I had just solved the problem I had before, anyway, thank you a million because you were right. Regarding your question of how I will know who has and who does not have those pets, I have already solved it in the first model that I published in my post. In which you use httpService:GenerateGuid(false) to create an id in the req and then code check that the req is from the player. I also plan to use PetsFolder:FindFirstChild(player.UserId) instead of PetsFolder:FindFirstChild(player.Name) to make it easier to know which pet each player is. I hope that answered your question, thank you a million, I leave a video with the final result in a different game than the two that I published previously

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.