How to have multiple pets equipped

So, I want to know how to make a certain number of pets form around you in a circle and follow you in that circle while you move around.
I know how to make it so you can have one equipped and follow you but the problems there are, it doesn’t stay in one “corner” of your character and it doesn’t work with multiple pets they will just end up in the same spot

Looking for something like this standing still:

And this for moving:

3 Likes

On your script where you have the pet location you can add more on the direction for example. FirstPetLocation + Vector3.new(5,0,5) .

2 Likes

that wouldn’t really work with more pets though just 2

2 Likes

Could I see a picture of what’s happening to your pets and the script.

2 Likes

im currently in class rn so i can’t show a script or picture but basically i made a script where it puts a pet behind and to the side of your character but if i add/equip more they will just stay in the same spot and want to know how to make them in a circle

1 Like

Hopefully you have a basic understanding of CFrame. If I understand correctly, you want a perfect circle formation around the player, depending on how many pets there are. From the way you wrote it, it sounds like you already have a system in place, but their positioning isn’t correct.

That said, here is how I would get the angle and position for each pet.

local PetTable = PetHolder:GetChildren() -- Obviously alter this to fit your environment.
local PetOffset = CFrame.new(0,0,4) -- Change this to offset your pet right.

for i, Pet in pairs(PetTable) do
     local Offset = 0 and #PetTable % 2 == 0 or 0.5
     local Angle = ((i + Offset) / #PetHolder:GetChildren()) * math.pi * 2
     local Position = HumanoidRootPart.CFrame * CFrame.Angles(0,Angle,0) * PetOffset
     
     -- Use this position accordingly.
end
3 Likes

thanks, i’ll be sure to test this out as soon as possible and get back to you

2 Likes

quick question though, inside of the for loop i just position pet to be position right

2 Likes

It just depends how you have it set up. Most of my variables, excluding the math, are vague with variable usage. That said, I would recommend using some type of BodyMover to move the pets smoothly.

1 Like

and then with the bodymover i set thats position to position

1 Like

I took a similar approach as @MattPrograms to the problem. But the only key difference is mine was taking into account the number of pets a player has equipped and ensuring the circle would have a radius large enough to fit the pets without causing for overlap. I made the function in a LocalScript since I assumed that would be the easiest method to set this up because presumably the players would be setting their active pets from a GUI and when it comes to pet movement it will look smoothest when run on the client.

By no means trying to take the spotlight away from @MattPrograms and I would still credit them with this. I was just throwing in the idea of ensuring the pets would have space between each other and not become a big blob around the player in large amounts.

local function setPetNodes(petCount,overlapMultipler)
	local rotationOffset = 360/petCount --Determine how much degrees must be seperated between pets
	for petNode = 1,petCount do
		local currentNode = Instance.new("Part")
		currentNode.Name = "Pet Node "..petNode
		currentNode.Size = Vector3.new(1,1,1)
		currentNode.CFrame = CFrame.Angles(0,math.rad(rotationOffset*petNode),0) * CFrame.new(-game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame.LookVector*math.max(petCount*overlapMultipler,4)) * game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame
		local weld = Instance.new("WeldConstraint")
		weld.Parent = currentNode
		weld.Part0 = game.Players.LocalPlayer.Character.HumanoidRootPart
		weld.Part1 = currentNode
		currentNode.Parent = game.Players.LocalPlayer.Character
	end
end

To those who want to let players equip hundreds of pets enjoy!

3 Likes

how would i implement this into my system/with the one @MattPrograms did

1 Like

Change PetOffset to

CFrame.new(0,0,OverlapMultiplier * #PetTable)

Define OverlapMultiplier accordingly.

2 Likes

i don’t follow, if i used the one you made how would i put the one @xZylter made (confused on where to put things)

1 Like

local Position = HumanoidRootPart.CFrame * CFrame.Angles(0,Angle,0) * PetOffset

should be…

local Position = HumanoidRootPart.CFrame * CFrame.Angles(0,Angle,0) * CFrame.new(0,0,math.clamp(OverlapMultiplier * #PetTable,4,math.huge)

The reason for the math.clamp is to prevent the pets from getting to close.

ah i see now, and then i just position the pets into “position”

Rather than:

math.clamp(OverlapMultiplier * #PetTable,4,math.huge)

Couldn’t you just do:

math.max(OverlapMultiplier * #PetTable, 4)

Oh yeah thanks for reminding me that those functions exist. I was wondering to myself if it does.

Sorry for the late reply but,

Heres my positioning code:

local clone = petModel:Clone()
		petModel.Equipped.Value = true
		clone.Parent = game.Players.LocalPlayer.Character
		clone:SetPrimaryPartCFrame(game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame)

		local attachChar = Instance.new("Attachment")
		attachChar.Visible = false
		attachChar.Parent = game.Players.LocalPlayer.Character.HumanoidRootPart
		attachChar.Position = --pos

		local attachPet = Instance.new("Attachment")
		attachPet.Visible = false
		attachPet.Parent = clone.PrimaryPart

		local alignPos = Instance.new("AlignPosition")
		alignPos.MaxForce = 25000
		alignPos.Attachment0 = attachPet
		alignPos.Attachment1 = attachChar
		alignPos.Responsiveness = 10
		alignPos.Parent = clone

		local alignOr = Instance.new("AlignOrientation", clone)
		alignOr.MaxTorque = 25000
		alignOr.Attachment0 = attachPet
		alignOr.Attachment1 = attachChar
		alignOr.Responsiveness = 10

how would i implent yours and @MattPrograms code into it

The code I posted was used to create the nodes for the pets to follow so you would need to use your AlignPostion and AlignOrientation code snippets and assign each pet to one of those nodes.

local alignPos = Instance.new("AlignPosition")
		alignPos.MaxForce = 25000
		alignPos.Attachment0 = attachPet
		alignPos.Attachment1 = attachChar --Instead of attaching to the character have it attach to one of the nodes
		alignPos.Responsiveness = 10
		alignPos.Parent = clone

		local alignOr = Instance.new("AlignOrientation", clone)
		alignOr.MaxTorque = 25000
		alignOr.Attachment0 = attachPet
		alignOr.Attachment1 = attachChar --Instead of attaching to the character have it attach to one of the nodes
		alignOr.Responsiveness = 10