Pet follow module [Simulator style]

Can I see an example of how the different functions would work? I’ve tried to use the add pet and the pets wouldn’t move. An example would be great

Fixed the issue where pets won’t show on other players at sometimes.
Here is the fixed one.

Use PetModule:AddPet(player, petName) to spawn pet to the specified player. Using PetModule:AddPet(PetName) will add it to localPlayer just like the author said.

local PetFollowModule = {}
local ModuleFunctions = {}
local ActivePets = {}

local Settings = require(script.Settings)
local LocalPlayer = game.Players.LocalPlayer

local YPoint = 0
local Addition = Settings.YDriftSpeed
local FullCircle = 2 * math.pi

local RunService = game:GetService("RunService")

function SetPetCollisions(Model)
	for _, Part in pairs(Model:GetDescendants()) do
		if Part:IsA("BasePart") then
			Part.CanCollide = false
			Part.Anchored = true
		end
	end
end

function getXAndZPositions(Angle, Radius)
	local x = math.cos(Angle) * Radius
	local z = math.sin(Angle) * Radius
	
	return x, z
end

function ModuleFunctions:AddPet(Player, PetName)
	print(1)
	if not PetName then
		PetName = Player 
		Player = LocalPlayer 
	end
	
	print(1)
	local PetModel = Settings.PetFolder[PetName]:Clone()
	PetModel.Parent = ActivePets[Player.UserId]
	print(1)
	if Player.Character then PetModel:SetPrimaryPartCFrame(Player.Character.PrimaryPart.CFrame) end
	print(1)
	SetPetCollisions(PetModel)
	print(1)
	return PetModel
end

function UpdatePetPositions()
	YPoint = YPoint + Addition
	if YPoint > Settings.YDrift or YPoint < -1 * Settings.YDrift then Addition = -1 * Addition end 
	
	for Id, Folder in pairs(ActivePets) do
		if Folder.Parent == game.Workspace then
			local Player = game.Players:GetPlayerByUserId(Id)
			local Character = Player.Character
			
			if Character  then
				local PetTable = Folder:GetChildren()
				local PetTableLength = #PetTable
				local Count = 0
				
				for _, Pet in pairs(PetTable) do
					Count += 1

					local Angle = Count * (FullCircle / PetTableLength)
					local X, Z = getXAndZPositions(Angle, Settings.Radius + (PetTableLength / 2))
					local Position = (Character.PrimaryPart.CFrame * CFrame.new(X, YPoint, Z)).p
					local LookAt = Character.PrimaryPart.Position
					local TargetCFrame = CFrame.new(Position, LookAt)
								
					local NewCFrame = Pet.PrimaryPart.CFrame:Lerp(TargetCFrame, Settings.Responsivness)
					Pet:SetPrimaryPartCFrame(NewCFrame)
				end
			end
		end
	end
end

function ModuleFunctions:RemovePet(Player, PetId)
	if not PetId then PetId = Player Player = LocalPlayer end
	ActivePets[Player.UserId][PetId]:Destroy()
end

function ModuleFunctions:HidePets(Player)
	ActivePets[Player.UserId].Parent = game.ReplicatedStorage
end

function ModuleFunctions:HideOthersPets()
	Settings.OtherPetsVisible = false
	
	for Id, Folder in pairs(ActivePets) do
		if Id ~= LocalPlayer.UserId then
			Folder.Parent = game.ReplicatedStorage
		end
	end
end

function ModuleFunctions:HideAllPets()
	Settings.AllPetsVisible = false
	
	for Id, Folder in pairs(ActivePets) do
		Folder.Parent = game.ReplicatedStorage
	end
end

function ModuleFunctions:ShowPets(Player)
	ActivePets[Player.UserId].Parent = game.Workspace
end

function ModuleFunctions:ShowOthersPets()
	Settings.OtherPetsVisible = true
	
	for Id, Folder in pairs(ActivePets) do
		if Id ~= LocalPlayer.UserId then
			Folder.Parent = game.Workspace
		end
	end
end

function ModuleFunctions:ShowAllPets()
	Settings.AllPetsVisible = true
	
	for Id, Folder in pairs(ActivePets) do
		Folder.Parent = game.Workspace
	end
end

function AddPlayer(Player)
	if not ActivePets[Player.UserId] then
		print(Player)
		ActivePets[Player.UserId] = Instance.new("Folder")
		ActivePets[Player.UserId].Name = Player.Name
		

		if Settings.OtherPetsVisible and Settings.AllPetsVisible then
			ActivePets[Player.UserId].Parent = game.Workspace
		else
			ActivePets[Player.UserId].Parent = game.ReplicatedStorage
		end
	end
	
end

game.Players.PlayerAdded:Connect(AddPlayer)
for i,pl in pairs(game.Players:GetPlayers()) do
	AddPlayer(pl)
end

game.Players.PlayerRemoving:Connect(function(Player)
	ActivePets[Player.UserId]:Destroy()
end)

RunService:BindToRenderStep('Update', 1, UpdatePetPositions)

setmetatable(PetFollowModule, {__index = ModuleFunctions})
return PetFollowModule

Hi so is this still currently working and also could you give me an example on how to use this

Yes it does work. Read the documentation

could you give me an example code

Hey its not working when I call add pet the pet doesnt show up but no errors

this is my code

local PetModule = require(game.ServerStorage["Pet Follow"])

game.Players.PlayerAdded:Connect(function(player)
	PetModule:AddPet(player,"Ice Cube")
end)

now the pet shows up but doesnt follow me any fix???

Because you are storing it on the server and client doesn’t have access to the server. Store it in replicated storage. And call addPet from a local script

So can u give me a code example pls

Same as urs just locate it at replicated storage

it doesnt show for everyone so is it just client sided?

you explained it wonderfully. :smiley: