Help with pet system

You can write your topic however you want, but you need to answer these questions:
i want to make a pet system
that can have animations like collect all pets

I’ve been working on the animations for idle and walking, but initially, they don’t change based on whether I’m walking or not. It plays the walk animation, and when I switch to idle, it doesn’t switch but plays both simultaneously. When I try to stop one, it bugs out. Additionally, there’s an error related to the maximum animation tracks, and I believe this is happening because the remote keeps firing.
robloxapp-20240107-1835014.wmv (2.7 MB)

local RunService = game:GetService("RunService")

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 walk = false


local function playIdleAnimation(pet)
	local animController = pet:FindFirstChild("AnimationController")

	if animController then
		local anim = animController:FindFirstChild("Idle")

		if anim then
			local playAnim = animController:LoadAnimation(anim)
			playAnim:Play()
		else
			warn("Idle animation not found for pet: " .. pet.Name)
		end
	else
		warn("AnimationController not found for pet: " .. pet.Name)
	end
end

local function playWalkAnimation(pet)
	local animController = pet:FindFirstChild("AnimationController")

	if animController then
		local anim = animController:FindFirstChild("Walk")

		if anim then
			local playAnim = animController:LoadAnimation(anim)
			playAnim:Play()
		else
			warn("Walk animation not found for pet: " .. pet.Name)
		end
	else
		warn("AnimationController not found for pet: " .. pet.Name)
	end
end

local function positionPets(character, folder)
	for i, pet in pairs(folder:GetChildren()) do
		local petSpeed = 0.2
		local Attachment = pet.PrimaryPart:WaitForChild("Attachment")
		local BillboardGui = Attachment:WaitForChild("BillboardGui")
		local PetName_Txt = BillboardGui:WaitForChild("PetName")
		local PetRarity_Txt = BillboardGui:WaitForChild("PetRarity")
		BillboardGui.Enabled = true
		PetName_Txt.Text = pet.Name
		PetRarity_Txt.Text = pet:GetAttribute("Rarity_Name")
		PetRarity_Txt.TextColor3 = pet:GetAttribute("Rarity_Color")

		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

		if character.Humanoid.MoveDirection.Magnitude > 0 then
			if pet:FindFirstChild("Walks") then
				if not walk then
					walk = true
					playWalkAnimation(pet)
				end

				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY, z), petSpeed))
				print("Walk")
			else
				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY, z), petSpeed))
			end
		else
			if pet:FindFirstChild("Walks") then
				if walk then
					walk = false
					print("idle")
					playIdleAnimation(pet)
				end

				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY, z), petSpeed))
				pet:PivotTo(CFrame.new(pet.PrimaryPart.Position, character.PrimaryPart.Position))
			else
				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY / 2 + math.sin(time() * 3) + 1, z), petSpeed))
			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)

Define the animations outside of the functions, then load and Stop/Play both respectively inside the functions, like this:

local RunService = game:GetService("RunService")

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 walk = false
local walkAnimation, idleAnimation

local function playIdleAnimation(pet)
	local animController = pet:FindFirstChild("AnimationController")

	if animController then
		if walkAnimation then
			walkAnimation:Stop() -- i forgot what the stop function is called
		end
		if not idleAnimation then
			idleAnimation = animController:LoadAnimation(animController.Idle)
		end
		task.wait()
		idleAnimation:Play()
	else
		warn("AnimationController not found for pet: " .. pet.Name)
	end
end

local function playWalkAnimation(pet)
	local animController = pet:FindFirstChild("AnimationController")

	if animController then
		if idleAnimation then
			idleAnimation:Stop() -- i forgot what the stop function is called
		end
		if not idleAnimation then
			walkAnimation = animController:LoadAnimation(animController.Walk)
		end
		task.wait()
		walkAnimation:Play()
	else
		warn("AnimationController not found for pet: " .. pet.Name)
	end
end

local function positionPets(character, folder)
	for i, pet in pairs(folder:GetChildren()) do
		local petSpeed = 0.2
		local Attachment = pet.PrimaryPart:WaitForChild("Attachment")
		local BillboardGui = Attachment:WaitForChild("BillboardGui")
		local PetName_Txt = BillboardGui:WaitForChild("PetName")
		local PetRarity_Txt = BillboardGui:WaitForChild("PetRarity")
		BillboardGui.Enabled = true
		PetName_Txt.Text = pet.Name
		PetRarity_Txt.Text = pet:GetAttribute("Rarity_Name")
		PetRarity_Txt.TextColor3 = pet:GetAttribute("Rarity_Color")

		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

		if character.Humanoid.MoveDirection.Magnitude > 0 then
			if pet:FindFirstChild("Walks") then
				if not walk then
					walk = true
					playWalkAnimation(pet)
				end

				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY, z), petSpeed))
				print("Walk")
			else
				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY, z), petSpeed))
			end
		else
			if pet:FindFirstChild("Walks") then
				if walk then
					walk = false
					print("idle")
					playIdleAnimation(pet)
				end

				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY, z), petSpeed))
				pet:PivotTo(CFrame.new(pet.PrimaryPart.Position, character.PrimaryPart.Position))
			else
				pet:SetPrimaryPartCFrame(pet.PrimaryPart.CFrame:Lerp(character.PrimaryPart.CFrame * CFrame.new(x, offsetY / 2 + math.sin(time() * 3) + 1, z), petSpeed))
			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)
1 Like

Thanks so much man really helped

Sorry there one last problem its not playing for all the pets equipped.
robloxapp-20240107-1937254.wmv (1.5 MB)

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