Pet Following Help

  1. What do you want to achieve? Keep it simple and clear!
    I want to achieve a pet following system where the pets are in rows and columns behind the player.

  2. What is the issue? Include screenshots / videos if possible!
    I’m having issues trying to figure out how to get the Bigger pets I have to be in the very back of all the pets when equipped. I got the normal pets to work fine.

image_2023-09-23_023100687
image_2023-09-23_023622871
https://gyazo.com/dbd97f05c69c5228756b6ef4acb8f682

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I’ve tried googling it, Ive asked a couple of developer friends. I tried using chat gpt but nothing worked.

In the screen shots you can see that the normal pets work fine, but when I equip the bigger pet it doesnt lock itself to the back of the character. In the gyazo I show what happens when the big pet gets equipped. I want the big pet to automatically get put in the back of whatever pets already equipped.

This is my code so far so any help is appreciated.

function PetClass:FollowCharacter()
	if self.Connection ~= nil then
		self.Connection:Disconnect()
	end

	self.Connection = RunService.Heartbeat:Connect(function(deltaTime: number)
		local folder = self.RenderedPets
		local character = self.Player.Character

		-- Define the number of rows and columns for the pets
		local numRows = 2  -- Adjust as needed
		local numColumns = 2  -- Adjust as needed
		local distance = 3  -- Adjust the distance between pets as needed

		-- Define bobbing parameters
		local bobbingAmplitude = 0.3  -- Adjust the amplitude of the bobbing
		local bobbingFrequency = 0.3  -- Adjust the frequency of the bobbing (slower)

		-- Define the additional orientation offset (in radians)
		local bigPetOrientationOffset = math.rad(0)  -- Adjust this value to make big pets look in the correct direction
		local normalPetOrientationOffset = math.rad(-90)  -- Adjust this value to make normal pets look in the correct direction

		-- Define the vertical offset for big pets
		local bigPetVerticalOffset = 6  -- Adjust this value to raise big pets above the ground

		local function getPosition(row, col, distance)
			-- Calculate the position for each pet in columns centered behind the player
			local xOffset = (col - (numColumns + 1) / 2) * distance
			local zOffset = (row - 0) * distance
			return xOffset, zOffset
		end

		local playerRootPart = character:FindFirstChild("HumanoidRootPart")
		if not playerRootPart then
			return  -- HumanoidRootPart not found, exit
		end

		local playerPosition = playerRootPart.Position

		local bigPets = {}
		local normalPets = {}

		for i, pet in pairs(folder:GetChildren()) do
			-- Check if the pet is a big pet based on an attribute
			local isBigPet = pet:GetAttribute("IsBigPet") == true

			-- Calculate the row and column for the pet
			local row = math.floor((i - 1) / numColumns) + 1
			local col = (i - 1) % numColumns + 1

			-- Calculate the position for the pet in columns centered behind the player
			local xOffset, zOffset = getPosition(row, col, distance)

			-- Calculate the yOffset with bobbing effect
			local time = tick()
			local yOffset = bobbingAmplitude * math.sin(2 * math.pi * bobbingFrequency * time)

			-- Calculate the pet's position directly behind the player
			local petTargetPosition = playerPosition - playerRootPart.CFrame.rightVector * xOffset - playerRootPart.CFrame.lookVector * zOffset

			-- Modify the position based on pet size
			local _, petSize = pet:GetBoundingBox()
			local sizeOffset = (petSize - Vector3.new(1, 1, 1)) / 2

			-- Use lerp for smoother motion
			local smoothness = 0.5  -- Adjust this value for smoother or more abrupt motion
			local currentPetPosition = pet.PrimaryPart.Position
			local newPetPosition = currentPetPosition:Lerp(petTargetPosition + Vector3.new(0, yOffset, 0) - sizeOffset, smoothness)

			-- Calculate the orientation LookAt CFrame towards the player's HumanoidRootPart
			local orientationCFrame = CFrame.new(newPetPosition, playerPosition)

			-- Apply an orientation offset for big pets
			if isBigPet then
				-- Add vertical offset to raise big pets above the ground
				yOffset = yOffset + bigPetVerticalOffset

				-- Calculate the orientation LookAt CFrame towards the player's HumanoidRootPart for big pets
				orientationCFrame = CFrame.new(newPetPosition, playerPosition) * CFrame.Angles(0, bigPetOrientationOffset, 0)
			else
				-- Calculate the orientation LookAt CFrame towards the player's HumanoidRootPart for normal pets
				orientationCFrame = CFrame.new(newPetPosition, playerPosition) * CFrame.Angles(0, normalPetOrientationOffset, 0)
			end

			pet:SetPrimaryPartCFrame(orientationCFrame + Vector3.new(0, yOffset, 0))
		end
	end)
end