Help With Pet System

  1. So Im creating a pet system but I am having issues with my pet following system.

  2. The issue is the pets show only on the client but I want it to show for everyone.

  3. I tried finding a similar problem but havent found any that matched what im dealing with.

local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlayerPets = workspace:WaitForChild("Player_Pets")

local Circle = math.pi * 2

local function GetPosition(angle, radius)
	local x = math.cos(angle) * radius
	local z = math.sin(angle) * radius
	return x, z
end

local function PositionPets(character, folder)
	for i, pet in pairs(folder:GetChildren()) do
		local radius = 4 + #folder:GetChildren()
		local angle = i * (Circle / #folder:GetChildren())
		local x, z = GetPosition(angle, radius)
		local _, characterSize = character:GetBoundingBox()
		local _, petSize = pet:GetBoundingBox()

		local offsetY = -characterSize.Y / 2 + petSize.Y / 2
		local sin = (math.sin(15 * time() + 1.6) / 0.5) + 1
		local cos = math.cos(7 * time() + 1) / 4

		if character.Humanoid.MoveDirection.Magnitude > 0 then
			if pet:FindFirstChild("Walks") then
				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY + sin, z) * CFrame.fromEulerAnglesXYZ(0, 0, cos), 0.1))
			else
				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY / 2 + math.sin(time() * 3) + 1, z), 0.1))
			end
		else
			if pet:FindFirstChild("Walks") then
				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY, z), 0.1))
			else
				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY / 2 + math.sin(time() * 3) + 1, z), 0.1))
			end
		end
	end
end

RunService.RenderStepped: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)

2 Likes

Any help is appreciated as im kind of loss.

1 Like

You need to use AlignPosition and AlignOrientation.
Use AlignPosition, and AlignOrientation on the client,
Then Use NetworkOwner by setting the NetworkOwner of the pet parts to the player.
That should allow it for the client to control the part with body movers.

I’m trying to save your local way of doing this, but I fear this may be just craziness.

Good Luck
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PlayerPets = workspace:WaitForChild("Player_Pets")

local Circle = math.pi * 2

local function GetPosition(angle, radius)
    local x = math.cos(angle) * radius
    local z = math.sin(angle) * radius
    return x, z
end

local function PositionPets(character, folder)
    for i, pet in pairs(folder:GetChildren()) do
        local radius = 4 + #folder:GetChildren()
        local angle = i * (Circle / #folder:GetChildren())
        local x, z = GetPosition(angle, radius)
        local _, characterSize = character:GetBoundingBox()
        local _, petSize = pet:GetBoundingBox()

        local offsetY = -characterSize.Y / 2 + petSize.Y / 2
        local sin = (math.sin(15 * tick() + 1.6) / 0.5) + 1
        local cos = math.cos(7 * tick() + 1) / 4

        if character.Humanoid.MoveDirection.Magnitude > 0 then
            if pet:FindFirstChild("Walks") then
                pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY + sin, z) * CFrame.fromEulerAnglesXYZ(0, 0, cos), 0.1))
            else
                pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY / 2 + math.sin(tick() * 3) + 1, z), 0.1))
            end
        else
            if pet:FindFirstChild("Walks") then
                pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY, z), 0.1))
            else
                pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY / 2 + math.sin(tick() * 3) + 1, z), 0.1))
            end
        end
        
        -- Replicate the pet's position to all clients
        local RemoteEvent = ReplicatedStorage:FindFirstChild("ReplicatePetPosition")
        if RemoteEvent then
            RemoteEvent:FireAllClients(pet, pet.PrimaryPart.CFrame)
        end
    end
end

-- Create the RemoteEvent in ReplicatedStorage if it doesn't exist
local RemoteEvent = ReplicatedStorage:FindFirstChild("ReplicatePetPosition")
if not RemoteEvent then
    RemoteEvent = Instance.new("RemoteEvent")
    RemoteEvent.Name = "ReplicatePetPosition"
    RemoteEvent.Parent = ReplicatedStorage
end

RunService.RenderStepped: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)
2 Likes

It says fireallclients cannot be fired on the client but on the server

1 Like

Probably, no real way to test your pet system from here …
I use a server based pet system.

Do I need to transfer this to a Server script?

Well if you don’t you’ll have to do some crazy script like I attempted.
That may lead to problems anyways, if there are pets / many pets on many players.