I’m trying to make a pet system, part of this is using viewports to give a preview of the pet, I have a module script to setup a viewport with a given pet, this has worked so far but sometimes it doesn’t and I don’t know why.
I also added a refresh button to reload all the viewports, but that didn’t work. It isn’t that efficient but it worked.
Gifs
https://gyazo.com/542f3cb57383e88872bc5ac18c5d870f
Code
PetViewport
--[[
DevTops
puts the valid stuff into a viewport to make it a pet thingy idk just trust me dude
]]
local replicatedStorage = game:GetService("ReplicatedStorage")
local pets = replicatedStorage:WaitForChild("Pets")
local PV = {}
function PV.setup(viewport, petName, folder)
folder:ClearAllChildren()
if not pets:FindFirstChild(petName) then return end
local clonedPet = pets:FindFirstChild(petName):Clone()
local camera = Instance.new("Camera", viewport)
viewport.CurrentCamera = camera
clonedPet.Parent = folder
local primPart = clonedPet.PrimaryPart
local _, size = clonedPet:GetBoundingBox()
camera.CFrame = CFrame.new((primPart.CFrame - Vector3.new(size.X + 1, 0, 0)).Position, primPart.CFrame.Position)
spawn(function()
game:GetService("RunService").RenderStepped:Connect(function()
if not clonedPet.PrimaryPart then return end
clonedPet:SetPrimaryPartCFrame(clonedPet:GetPrimaryPartCFrame() * CFrame.fromEulerAnglesXYZ(0, 0.025, 0))
end)
end)
end
return PV
LoadPets - Loads pets from the player’s pets into UI elements the user can interact with
local petAdder = require(script.Parent:WaitForChild("PetAdder"))
local petsList = script.Parent:WaitForChild("Pets"):WaitForChild("Pets")
local player = game.Players.LocalPlayer
local data = player:WaitForChild("data")
local pets = data:WaitForChild("pets")
local equipedPets = data:WaitForChild("equipedPets")
local selectedPetValue = script.Parent:WaitForChild("SelectedFrame"):WaitForChild("Pet")
local gamepasses = player:WaitForChild("gamepasses")
local refresh = script.Parent:WaitForChild("Refresh"):WaitForChild("Button")
local replicatedStorage = game:GetService("ReplicatedStorage")
local modules = replicatedStorage:WaitForChild("Modules")
local equations = require(modules:WaitForChild("Equations"))
local purchaseLib = require(modules:WaitForChild("PurchaseLib"))
local genericButton = require(script.Parent.Parent.Parent:WaitForChild("GenericButton"))
genericButton.hook(refresh)
local infPetEquip = purchaseLib.api.getFromName("InfPetsEquipped")
local infPetStorage = purchaseLib.api.getFromName("InfPetsStorage")
local function loadAll()
petsList.CanvasSize = UDim2.fromScale(1, 0)
local function addSize() petsList.CanvasSize += UDim2.fromOffset(0, 20) end
local amountOfPets = #pets:GetChildren() + #equipedPets:GetChildren()
for _, child in pairs(petsList:GetChildren()) do if child:IsA("Frame") then child:Destroy() end end
for _, pet in pairs(pets:GetChildren()) do petAdder.addPet(pet.Value); addSize(); end
for _, pet in pairs(equipedPets:GetChildren()) do petAdder.addPet(pet.Value, true); addSize(); end
end
loadAll()
pets.ChildAdded:Connect(loadAll)
pets.ChildRemoved:Connect(loadAll)
equipedPets.ChildAdded:Connect(loadAll)
equipedPets.ChildRemoved:Connect(loadAll)
refresh.MouseButton1Click:Connect(loadAll)
PetAdder - Take a pet and makes a UI element with it
local replicatedStorage = game:GetService("ReplicatedStorage")
local pets = replicatedStorage:WaitForChild("Pets")
local petList = script.Parent:WaitForChild("Pets"):WaitForChild("Pets")
local selectedPetValue = script.Parent:WaitForChild("SelectedFrame"):WaitForChild("Pet")
local equipButton = script.Parent:WaitForChild("SelectedFrame"):WaitForChild("EquipButton"):WaitForChild("Button")
local modules = replicatedStorage:WaitForChild("Modules")
local petViewport = require(modules:WaitForChild("PetViewport"))
local petPrefab = script:WaitForChild("PetPrefab")
local PA = {}
function PA.addPet(petObject, equiped)
equiped = equiped or false
if type(petObject) == "string" then petObject = pets:WaitForChild(petObject) end
local clonedPrefab = petPrefab:Clone()
local petImage = clonedPrefab:WaitForChild("PetImage")
local selectButton = clonedPrefab:WaitForChild("Button")
local petName = clonedPrefab:WaitForChild("PetName")
petViewport.setup(petImage, petObject.Name, petImage:WaitForChild("Dispose"))
if equiped then petImage.ImageColor3 = Color3.fromRGB(0, 255, 0); clonedPrefab.LayoutOrder = 0; end
clonedPrefab.Parent = petList
petName.Text = petObject.Name
selectButton.MouseButton1Click:Connect(function()
if selectedPetValue.Value ~= petObject then selectedPetValue.Value = petObject else selectedPetValue.Value = nil end
end)
local function updateSelectedPet() if selectedPetValue.Value == petObject then petName.Font = Enum.Font.ArialBold else petName.Font = Enum.Font.Cartoon end end
selectedPetValue.Changed:Connect(updateSelectedPet)
updateSelectedPet()
if selectedPetValue.Value == petObject then selectedPetValue.Value = nil; selectedPetValue.Value = petObject; end
return clonedPrefab
end
function PA.removePet(petObject)
if type(petObject) == "userdata" then petObject = petObject.Name end
local found = petList:FindFirstChild(petObject)
if not found then return end
found:Destroy()
end
return PA
If I missed anything lmk but I’ve been confused by this for about 30 minutes