Pet templates not cloning

My pet template doesn’t clone most of the time.
On start up the pet templates don’t clone, and I’m not getting any errors.

I have a script that is supposed to clone a gui template, however it doesn’t work most of the time, even if start it up after it working and not changing any code. I figure this might be a roblox issue, though I’m sure there any way to enhance my code so it does work.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")

local Handler = require(script.Parent.Handler)
local Remotes = ReplicatedStorage.Remotes
local PetsConfig = require(ReplicatedStorage.Config.Pets)
local PetModels = ReplicatedStorage.Pets
local player = Players.LocalPlayer

local screenGUI = script.Parent
local frame = screenGUI.Frame
local container = frame.Container.Container
local info = frame.Info

local petInfo = info.Pet

local exit = frame.ExitButton

local template = container.Template

local function GetRarityColor(rarity: string)
	local color

	if rarity == "Common" then
		color = Color3.fromRGB(255, 255, 255)
	elseif rarity == "Uncommon" then
		color = Color3.fromRGB(34, 255, 0)
	elseif rarity == "Rare" then
		color = Color3.fromRGB(18, 93, 249)
	elseif rarity == "Legendary" then
		color = Color3.fromRGB(234, 32, 251)
	elseif rarity == "Mythical" then
		color = Color3.fromRGB(251, 204, 6)
	end

	return color
end


local function GenerateViewportFrame(viewportFrame: ViewportFrame, petModel: Model)
	petModel:PivotTo(CFrame.new() * CFrame.Angles(0, math.rad(90), 0))
	petModel.Parent = viewportFrame

	local camera = Instance.new("Camera", viewportFrame)
	viewportFrame.CurrentCamera = camera

	camera.CFrame = CFrame.new(Vector3.new(0, 0, 2.7), petModel.PrimaryPart.Position)
end

local function DisplayPetInfo(pet: table)
	local petStat = PetsConfig[pet.ID][pet.Rarity]
	local petInstance = player.petInventory:FindFirstChild(pet.UUID)

	petInfo.PetName.Text = pet.ID:gsub("_", " ")
	petInfo.Rarity.Text = pet.Rarity
	petInfo.Rarity.TextColor3 = GetRarityColor(pet.Rarity)
	petInfo.StatsFrame.NotesStat.Text = "♫x"..petStat
	petInfo.StatsFrame.MoneyStat.Text = "💰x"..petStat

	local petModel = PetModels[pet.ID]:Clone()
	GenerateViewportFrame(petInfo.ViewportFrame, petModel)

	if petInstance.Equipped.Value then
		petInfo.EquipButton.Text = "Unequip"
		petInfo.EquipButton.BackgroundColor3 = Color3.fromRGB(209, 16, 9)
	else
		petInfo.EquipButton.Text = "Equip"
		petInfo.EquipButton.BackgroundColor3 = Color3.fromRGB(1, 209, 32)
	end
end

local function GeneratePet(pet: table)
	local clone = template:Clone()
	clone.Visible = true
	clone.Parent = container
	clone.Name = pet.UUID
	clone.Holder.PetName.Text = pet.ID:gsub("_", " ")
	clone.Holder.Equipped.Visible = pet.Equipped
	
	local petModel = PetModels[pet.ID]:Clone()
	GenerateViewportFrame(clone.Holder.ViewportFrame, petModel)
	
	clone.MouseButton1Click:Connect(function()
		DisplayPetInfo(pet)
		petInfo.Visible = true
	end)
end

local function PetInstanceToTable(pet: Instance)
	local newPet = {}
	newPet.UUID = pet.Name
	newPet.ID = pet.ID.Value
	newPet.Rarity = pet.Rarity.Value
	newPet.Equipped = pet.Equipped.Value
	return newPet
end

for _, pet in ipairs(player.petInventory:GetChildren()) do
	local petTable = PetInstanceToTable(pet)
	GeneratePet(petTable)
end

exit.MouseButton1Click:Connect(function()
	screenGUI.Enabled = false
end)



1 Like

Maybe the pets in player.petInventory are not created yet?

How should I ensure that the petInventory exists when the code is executed?

if petInventory would not exist you would get an error, I mean that the content of petInventory could be empty.

for _, pet in ipairs(player.petInventory:GetChildren()) do
        print(pet)
	local petTable = PetInstanceToTable(pet)
	GeneratePet(petTable)
end

Try printing the pet and see if there is any output.

I did not see anything in the output.

Ok that means there are no pets to clone.
What you can do is this:

player.petInventory.ChildAdded:Connect(GeneratePet)
put this at the end of your script.

It should look like this:

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")

local Handler = require(script.Parent.Handler)
local Remotes = ReplicatedStorage.Remotes
local PetsConfig = require(ReplicatedStorage.Config.Pets)
local PetModels = ReplicatedStorage.Pets
local player = Players.LocalPlayer

local screenGUI = script.Parent
local frame = screenGUI.Frame
local container = frame.Container.Container
local info = frame.Info

local petInfo = info.Pet

local exit = frame.ExitButton

local template = container.Template

local function GetRarityColor(rarity: string)
	local color

	if rarity == "Common" then
		color = Color3.fromRGB(255, 255, 255)
	elseif rarity == "Uncommon" then
		color = Color3.fromRGB(34, 255, 0)
	elseif rarity == "Rare" then
		color = Color3.fromRGB(18, 93, 249)
	elseif rarity == "Legendary" then
		color = Color3.fromRGB(234, 32, 251)
	elseif rarity == "Mythical" then
		color = Color3.fromRGB(251, 204, 6)
	end

	return color
end


local function GenerateViewportFrame(viewportFrame: ViewportFrame, petModel: Model)
	petModel:PivotTo(CFrame.new() * CFrame.Angles(0, math.rad(90), 0))
	petModel.Parent = viewportFrame

	local camera = Instance.new("Camera", viewportFrame)
	viewportFrame.CurrentCamera = camera

	camera.CFrame = CFrame.new(Vector3.new(0, 0, 2.7), petModel.PrimaryPart.Position)
end

local function DisplayPetInfo(pet: table)
	local petStat = PetsConfig[pet.ID][pet.Rarity]
	local petInstance = player.petInventory:FindFirstChild(pet.UUID)

	petInfo.PetName.Text = pet.ID:gsub("_", " ")
	petInfo.Rarity.Text = pet.Rarity
	petInfo.Rarity.TextColor3 = GetRarityColor(pet.Rarity)
	petInfo.StatsFrame.NotesStat.Text = "♫x"..petStat
	petInfo.StatsFrame.MoneyStat.Text = "💰x"..petStat

	local petModel = PetModels[pet.ID]:Clone()
	GenerateViewportFrame(petInfo.ViewportFrame, petModel)

	if petInstance.Equipped.Value then
		petInfo.EquipButton.Text = "Unequip"
		petInfo.EquipButton.BackgroundColor3 = Color3.fromRGB(209, 16, 9)
	else
		petInfo.EquipButton.Text = "Equip"
		petInfo.EquipButton.BackgroundColor3 = Color3.fromRGB(1, 209, 32)
	end
end

local function GeneratePet(pet: table)
	local clone = template:Clone()
	clone.Visible = true
	clone.Parent = container
	clone.Name = pet.UUID
	clone.Holder.PetName.Text = pet.ID:gsub("_", " ")
	clone.Holder.Equipped.Visible = pet.Equipped
	
	local petModel = PetModels[pet.ID]:Clone()
	GenerateViewportFrame(clone.Holder.ViewportFrame, petModel)
	
	clone.MouseButton1Click:Connect(function()
		DisplayPetInfo(pet)
		petInfo.Visible = true
	end)
end

local function PetInstanceToTable(pet: Instance)
	local newPet = {}
	newPet.UUID = pet.Name
	newPet.ID = pet.ID.Value
	newPet.Rarity = pet.Rarity.Value
	newPet.Equipped = pet.Equipped.Value
	return newPet
end

for _, pet in ipairs(player.petInventory:GetChildren()) do
	local petTable = PetInstanceToTable(pet)
	GeneratePet(petTable)
end

exit.MouseButton1Click:Connect(function()
	screenGUI.Enabled = false
end)

player.petInventory.ChildAdded:Connect(GeneratePet)

We keep the loop, just in case that there are already existing pets in the inventory, and if a new pet is added to petInventory, it will call the “GeneratePet” function (with the first argument is the new child) too - ChildAdded:Connect(function(newChild))

The pets were cloned, however they were all set to the default properties

Ahh yes I just see I made a mistake.

Create a new function:

function PetAdded(Pet)
GeneratePet(PetInstanceToTable(Pet))
end

And replace this: player.petInventory.ChildAdded:Connect(GeneratePet)
With this: player.petInventory.ChildAdded:Connect(PetAdded)

Now everything should work

Sorry, I’m confused about where I should put the function

Put the function anywhere in the script like this:

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")

local Handler = require(script.Parent.Handler)
local Remotes = ReplicatedStorage.Remotes
local PetsConfig = require(ReplicatedStorage.Config.Pets)
local PetModels = ReplicatedStorage.Pets
local player = Players.LocalPlayer

local screenGUI = script.Parent
local frame = screenGUI.Frame
local container = frame.Container.Container
local info = frame.Info

local petInfo = info.Pet

local exit = frame.ExitButton

local template = container.Template

local function GetRarityColor(rarity: string)
	local color

	if rarity == "Common" then
		color = Color3.fromRGB(255, 255, 255)
	elseif rarity == "Uncommon" then
		color = Color3.fromRGB(34, 255, 0)
	elseif rarity == "Rare" then
		color = Color3.fromRGB(18, 93, 249)
	elseif rarity == "Legendary" then
		color = Color3.fromRGB(234, 32, 251)
	elseif rarity == "Mythical" then
		color = Color3.fromRGB(251, 204, 6)
	end

	return color
end


local function GenerateViewportFrame(viewportFrame: ViewportFrame, petModel: Model)
	petModel:PivotTo(CFrame.new() * CFrame.Angles(0, math.rad(90), 0))
	petModel.Parent = viewportFrame

	local camera = Instance.new("Camera", viewportFrame)
	viewportFrame.CurrentCamera = camera

	camera.CFrame = CFrame.new(Vector3.new(0, 0, 2.7), petModel.PrimaryPart.Position)
end

local function DisplayPetInfo(pet: table)
	local petStat = PetsConfig[pet.ID][pet.Rarity]
	local petInstance = player.petInventory:FindFirstChild(pet.UUID)

	petInfo.PetName.Text = pet.ID:gsub("_", " ")
	petInfo.Rarity.Text = pet.Rarity
	petInfo.Rarity.TextColor3 = GetRarityColor(pet.Rarity)
	petInfo.StatsFrame.NotesStat.Text = "♫x"..petStat
	petInfo.StatsFrame.MoneyStat.Text = "💰x"..petStat

	local petModel = PetModels[pet.ID]:Clone()
	GenerateViewportFrame(petInfo.ViewportFrame, petModel)

	if petInstance.Equipped.Value then
		petInfo.EquipButton.Text = "Unequip"
		petInfo.EquipButton.BackgroundColor3 = Color3.fromRGB(209, 16, 9)
	else
		petInfo.EquipButton.Text = "Equip"
		petInfo.EquipButton.BackgroundColor3 = Color3.fromRGB(1, 209, 32)
	end
end

local function GeneratePet(pet: table)
	local clone = template:Clone()
	clone.Visible = true
	clone.Parent = container
	clone.Name = pet.UUID
	clone.Holder.PetName.Text = pet.ID:gsub("_", " ")
	clone.Holder.Equipped.Visible = pet.Equipped
	
	local petModel = PetModels[pet.ID]:Clone()
	GenerateViewportFrame(clone.Holder.ViewportFrame, petModel)
	
	clone.MouseButton1Click:Connect(function()
		DisplayPetInfo(pet)
		petInfo.Visible = true
	end)
end

local function PetInstanceToTable(pet: Instance)
	local newPet = {}
	newPet.UUID = pet.Name
	newPet.ID = pet.ID.Value
	newPet.Rarity = pet.Rarity.Value
	newPet.Equipped = pet.Equipped.Value
	return newPet
end

local function PetAdded(Pet)
GeneratePet(PetInstanceToTable(Pet))
end

for _, pet in ipairs(player.petInventory:GetChildren()) do
	local petTable = PetInstanceToTable(pet)
	GeneratePet(petTable)
end

exit.MouseButton1Click:Connect(function()
	screenGUI.Enabled = false
end)

player.petInventory.ChildAdded:Connect(PetAdded)

Dang it, now it doesn’t clone it at all

1 Like

You replaced this:
player.petInventory.ChildAdded:Connect(GeneratePet)
to this:
player.petInventory.ChildAdded:Connect(PetAdded)
?

Yes I did, however it is not working.

use :waitforchild() when looking for items that are instanced or cloned using code, because instancing or cloning has a slight delay

Dang, it will work once then just stop working after that

Did you check the Workspace to see if the objects were actually cloned and parented to the container object?

Yes, however they only get cloned while:
player.petInventory.ChildAdded:Connect(GeneratePet)
and not:
player.petInventory.ChildAdded:Connect(PetAdded)
but using player.petInventory.ChildAdded:Connect(GeneratePet) does not PetInstanceToTable

Every time I change the code and it ends up working, it will stop working upon reboot

Are you using any DataStores by any chance to save the pet info?

yes I am, the pets are folders in the players inventory, and those are working as they should.