(long script) Why is my inventory script not working?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    An inventory script that displays unit models when they’re added to the inventory, and when a multiple of 15 is reached the viewportframes are cloned (or rather, new ones are made with the same attributes) so more models can be displayed but they appear on another page.

  2. What is the issue? Include screenshots / videos if possible!
    It just stops cloning after 30 units and I have spent 2 days trying to solve this.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I looked for solutions here, read and reread many guides, even asked ai, but I still can not find what causes this.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
This is the code. It is very long, and kind of messy, but I need help and I’m running out of options:

local rs = game.ReplicatedStorage
local model1 = rs.Nooby.Noob
local model2 = rs.Snaky.Snake
local wmodel1 = rs.SmolNooby["Baby Noob"]
local wmodel2 = rs.Rabbi.Rabbit
local smodel1 = rs.SwordedNooby["Sword Noob"]
local smodel2 = rs.Turt.Turtle
local amodel1 = rs.AngeryNooby["Angry Noob"]
local amodel2 = rs.Kitten.Cat
local almodel1 = rs.AngerySmolNooby["Angry Baby Noob"]
local almodel2 = rs.Hammy.Hamster
local altmodel1 = rs.GladNooby["Gladiator Noob"]
local altmodel2 = rs.Doggo.Dog
local emodel1 = rs.SadNooby["Sad Noob"]
local emodel2 = rs.DocOc.Octopus
local ewmodel1 = rs.SadSmolNooby["Sad Baby Noob"]
local ewmodel2 = rs.Nugget.Chicken
local esmodel1 = rs.MassNooby["Massacre Noob"]
local esmodel2 = rs.SquidGame.Squid
local eff1 = rs.RadNooby["Radioactive Noob"]
local eff2 = rs.EffeSnak.Cobra
local ultrae1 = rs.EleNooby["Element Controller Noob"]
local ultrae2 = rs.EleSnaky.Viper
local bmodel1 = rs.BigNoob["Tank Noob"]
local bmodel2 = rs.LargSnak.Longsnake
local bbmodel1 = rs.SuperBigNoob["Super Tank Noob"]
local bbmodel2 = rs.BoaBuilder["Boa Constrictor"]
local umodel1 = rs.MonsterNoob["Monster Noob"]
local umodel2 = rs.Tort.Tortoise
local uumodel1 = rs.SuperMonsterNoob["Super Monster Noob"]
local uumodel2 = rs.GalaTort["Galapagos Tortoise"]
local bossmodel1 = rs.BiggerBrainNooby.Noobatron
local bossmodel2 = rs.BigLion["Nemean Lion"]
local bobomodel1 = rs.GiantNooby["Controller Noob"]
local bobomodel2 = rs.KrakBoy.Kraken
local rang1 = rs.SNooby["Soldier Noob"]
local rang2 = rs.SKitty["Spitter Cat"]
local arang1 = rs.SNooby2["Trooper Noob"]
local arang2 = rs.SDoggy["Bone Spitting Doge"]
local erang1 = rs.SNoobier["General Noob"]
local erang2 = rs.SeViper["Poison Beam Viper"]
local convert1 = rs.NNooby["Necromancer Noob"]
local convert2 = rs.TeacherRab["Summoner Rabbit"]
local coconvert1 = rs.ConnectNooby["Connection Noob"]
local coconvert2 = rs.NecroTort["Necromancer Tortoise"]
local suppo1 = rs.HealNooby["Healer Noob"]
local suppo2 =rs.HealKitty["Cat Named Galaxy Eater"]
local su1 = rs.DocNooby["Medic Noob"]
local su2 = rs.DocDoggy["Dog Named Princess"]
local off1 = rs.CyNooby["Cyclops Noob"]
local off2 = rs.EleRab["Electric Bunny"]
local def1 = rs.ShieldNooby["Shield Noob"]
local def2 = rs.LavTurt["Magma Turtley"]
local use1 = rs.DiffNooby["Super Noob"]
local use2 = rs.FreSnak["Cold Snake"]
local voff1 = rs.CyNooby2["Super Cyclops Noob"]
local voff2 = rs.EleRab2["Electro Rabbit"]
local vdef1 = rs.ShieldNooby2["Super Shield Noob"]
local vdef2 = rs.LavTurt2["Lava Turtle"]
local vuse1 = rs.DiffNooby2["Mega Noob"]
local vuse2 = rs.FreSnak2["Frosty Snake"]
local roff1 = rs.CyNooby3["Mega Cyclops Noob"]
local roff2 = rs.EleRab3["Bunny O'Lightning"]
local rdef1 = rs.ShieldNooby3["Mega Shield Noob"]
local rdef2 = rs.LavTurt3["Infernal Turtle"]
local ruse1 = rs.DiffNooby3["Omega Noob"]
local ruse2 = rs.FreSnak3["Snake Of Chill"]
local eoff1 = rs.CyNooby4["Ultra Cyclops Noob"]
local eoff2 = rs.EleRab4["Rabbit Of Thunder"]
local edef1 = rs.ShieldNooby4["Ultra Shield Noob"]
local edef2 = rs.LavTurt4["Tortoise From Hell"]
local euse1 = rs.DiffNooby4["Ultra Noob"]
local euse2 = rs.FreSnak4["Cobra Of Freeze"]
local final1 = rs.DiffNooby5["Hyper Noob"]
local final2 = rs.FreSnak5["TundraViper"]
local wm = script.Parent.ViewportFrame1.WorldModel
local wm2 = script.Parent.ViewportFrame2.WorldModel
local wm3 = script.Parent.ViewportFrame3.WorldModel
local pager = script.Parent.PageLabel -- current text is "page 1/1"

-- Keep track of which units have been displayed
local displayedUnits = {}

local function displayUnit(slotData, viewportFrame)
	-- Check if the inventory slot exists
	if slotData then
		-- Load the appropriate model based on the slot value
		local model
		if slotData.Value == 1 and slotData.Name == "Unit1" then
			model = model1 
		elseif slotData.Value == 2 and slotData.Name == "Unit1" then
			model = model2 
		elseif slotData.Value == 1 and slotData.Name == "Unit2" then
			model = wmodel1 
		elseif slotData.Value == 2 and slotData.Name == "Unit2" then
			model = wmodel2 
		elseif slotData.Value == 1 and slotData.Name == "Unit3" then
			model = smodel1 
		elseif slotData.Value == 2 and slotData.Name == "Unit3" then
			model = smodel2 
		elseif slotData.Value == 1 and slotData.Name == "Unit4" then
			model = amodel1 
		elseif slotData.Value == 2 and slotData.Name == "Unit4" then
			model = amodel2 
		elseif slotData.Value == 1 and slotData.Name == "Unit5" then
			model = almodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit5" then
			model = almodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit6" then
			model = altmodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit6" then
			model = altmodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit7" then
			model = emodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit7" then
			model = emodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit8" then
			model = ewmodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit8" then
			model = ewmodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit9" then
			model = esmodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit9" then
			model = esmodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit10" then
			model = eff1
		elseif slotData.Value == 2 and slotData.Name == "Unit10" then
			model = eff2
		elseif slotData.Value == 1 and slotData.Name == "Unit11" then
			model = ultrae1
		elseif slotData.Value == 2 and slotData.Name == "Unit11" then
			model = ultrae2
		elseif slotData.Value == 1 and slotData.Name == "Unit12" then
			model = bmodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit12" then
			model = bmodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit13" then
			model = bbmodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit13" then
			model = bbmodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit14" then
			model = umodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit14" then
			model = umodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit15" then
			model = uumodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit15" then
			model = uumodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit16" then
			model = bossmodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit16" then
			model = bossmodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit17" then
			model = bobomodel1
		elseif slotData.Value == 2 and slotData.Name == "Unit17" then
			model = bobomodel2
		elseif slotData.Value == 1 and slotData.Name == "Unit18" then
			model = rang1
		elseif slotData.Value == 2 and slotData.Name == "Unit18" then
			model = rang2
		elseif slotData.Value == 1 and slotData.Name == "Unit19" then
			model = arang1
		elseif slotData.Value == 2 and slotData.Name == "Unit19" then
			model = arang2
		elseif slotData.Value == 1 and slotData.Name == "Unit20" then
			model = erang1
		elseif slotData.Value == 2 and slotData.Name == "Unit20" then
			model = erang2
		elseif slotData.Value == 1 and slotData.Name == "Unit21" then
			model = convert1
		elseif slotData.Value == 2 and slotData.Name == "Unit21" then
			model = convert2
		elseif slotData.Value == 1 and slotData.Name == "Unit22" then
			model = coconvert1
		elseif slotData.Value == 2 and slotData.Name == "Unit22" then
			model = coconvert2
		elseif slotData.Value == 1 and slotData.Name == "Unit23" then
			model = suppo1
		elseif slotData.Value == 2 and slotData.Name == "Unit23" then
			model = suppo2
		elseif slotData.Value == 1 and slotData.Name == "Unit24" then
			model = su1
		elseif slotData.Value == 2 and slotData.Name == "Unit24" then
			model = su2
		elseif slotData.Value == 1 and slotData.Name == "Unit25" then
			model = off1
		elseif slotData.Value == 2 and slotData.Name == "Unit25" then
			model = off2
		elseif slotData.Value == 1 and slotData.Name == "Unit26" then
			model = def1
		elseif slotData.Value == 2 and slotData.Name == "Unit26" then
			model = def2
		elseif slotData.Value == 1 and slotData.Name == "Unit27" then
			model = use1
		elseif slotData.Value == 2 and slotData.Name == "Unit27" then
			model = use2
		elseif slotData.Value == 1 and slotData.Name == "Unit28" then
			model = voff1
		elseif slotData.Value == 2 and slotData.Name == "Unit28" then
			model = voff2
		elseif slotData.Value == 1 and slotData.Name == "Unit29" then
			model = vdef1
		elseif slotData.Value == 2 and slotData.Name == "Unit29" then
			model = vdef2
		elseif slotData.Value == 1 and slotData.Name == "Unit30" then
			model = vuse1
		elseif slotData.Value == 2 and slotData.Name == "Unit30" then
			model = vuse2
		elseif slotData.Value == 1 and slotData.Name == "Unit31" then
			model = roff1
		elseif slotData.Value == 2 and slotData.Name == "Unit31" then
			model = roff2
		elseif slotData.Value == 1 and slotData.Name == "Unit32" then
			model = rdef1
		elseif slotData.Value == 2 and slotData.Name == "Unit32" then
			model = rdef2
		elseif slotData.Value == 1 and slotData.Name == "Unit33" then
			model = ruse1
		elseif slotData.Value == 2 and slotData.Name == "Unit33" then
			model = ruse2
		elseif slotData.Value == 1 and slotData.Name == "Unit34" then
			model = eoff1
		elseif slotData.Value == 2 and slotData.Name == "Unit34" then
			model = eoff2
		elseif slotData.Value == 1 and slotData.Name == "Unit35" then
			model = edef1
		elseif slotData.Value == 2 and slotData.Name == "Unit35" then
			model = edef2
		elseif slotData.Value == 1 and slotData.Name == "Unit36" then
			model = euse1
		elseif slotData.Value == 2 and slotData.Name == "Unit36" then
			model = euse2
		elseif slotData.Value == 1 and slotData.Name == "Unit37" then
			model = final1
		elseif slotData.Value == 2 and slotData.Name == "Unit37" then
			model = final2
		else
			warn("Invalid slot value:", slotData.Value)
			return
		end

		-- Check if the unit has already been displayed
		if not table.find(displayedUnits,slotData) then
			-- Clone the model and parent it to the viewport frame
			local clonedModel = model:Clone()
			clonedModel.Parent = viewportFrame
			viewportFrame.WorldModel.Obj.Value = slotData
			-- Position the camera to focus on the cloned model
			local viewportCamera = Instance.new("Camera")
			viewportFrame.CurrentCamera = viewportCamera
			viewportCamera.Parent = viewportFrame
			viewportCamera.CFrame = CFrame.new(clonedModel.Head.Position + clonedModel.Head.CFrame.LookVector * (clonedModel.Head.Size.X * 2), clonedModel.Head.Position)
			-- Mark the unit as displayed
			if displayedUnits ~= nil then
				table.insert(displayedUnits, slotData)
			end
		end
	else
		warn("Slot data not found")
	end
end

-- Define a table to store references to the cloned viewport frames
local clonedViewportFrames = {}

-- Define variables to keep track of current page and total pages
local currentPage = 1
local totalPages = 1

-- Function to calculate total pages based on the number of units
local function calculateTotalPages()
	return math.ceil(#game.Players.LocalPlayer:WaitForChild("Inventory"):GetChildren() / 15)
end

-- Function to clone viewport frames and make them invisible
local function cloneViewportFrames()
	for i = 1, 15 do
		local originalViewportFrame = script.Parent["ViewportFrame" .. (i % 15+1)]
		local clonedViewportFrame = Instance.new("ViewportFrame")
		clonedViewportFrame.Size = originalViewportFrame.Size
		clonedViewportFrame.Position = originalViewportFrame.Position
		clonedViewportFrame.BorderSizePixel = originalViewportFrame.BorderSizePixel
		clonedViewportFrame.BackgroundTransparency = originalViewportFrame.BackgroundTransparency
		clonedViewportFrame.BackgroundColor3 = originalViewportFrame.BackgroundColor3
		clonedViewportFrame.BorderColor3 = originalViewportFrame.BorderColor3
		clonedViewportFrame.ClipsDescendants = originalViewportFrame.ClipsDescendants
		clonedViewportFrame.AnchorPoint = originalViewportFrame.AnchorPoint
		clonedViewportFrame.Visible = false -- Make the cloned viewport frames invisible
		clonedViewportFrame.Name = "ViewportFrame" .. i + 15

		-- Clone the UI stroke
		local uiStroke = originalViewportFrame:FindFirstChild("UIStroke")
		if uiStroke then
			uiStroke = uiStroke:Clone()
			uiStroke.Parent = clonedViewportFrame
		end

		-- Clone the hover script
		local hoverScript = originalViewportFrame:FindFirstChild("Hover")
		if hoverScript then
			hoverScript = hoverScript:Clone()
			hoverScript.Parent = clonedViewportFrame
		end
		
		-- Remove any existing model below the original viewport frame
		local existingModel = originalViewportFrame:FindFirstChildOfClass("Model")
		if existingModel and originalViewportFrame.Name~="ViewportFrame" .. (i + 15+1) then
			existingModel:Destroy()
		end

		-- Create a new WorldModel with a new ObjectValue named "Obj"
		local worldModel = Instance.new("Model")
		worldModel.Name = "WorldModel"
		local objValue = Instance.new("ObjectValue")
		objValue.Name = "Obj"
		worldModel.Parent = clonedViewportFrame
		objValue.Parent = worldModel

		clonedViewportFrame.Parent = script.Parent
		table.insert(clonedViewportFrames, clonedViewportFrame) -- Store reference to the cloned viewport frame
	end
end

-- Function to display units on the specified page
local function displayPageUnits(pageNumber)
	local startIndex = (currentPage - 1) * 15 + 1
	local endIndex = math.min(currentPage * 15, #displayedUnits)

	for i = startIndex, endIndex do
		local viewportFrameIndex = (i - 1) % 15 + 1
		if script.Parent["ViewportFrame" .. viewportFrameIndex] then
			script.Parent["ViewportFrame" .. viewportFrameIndex].Visible = true
			local unitData = displayedUnits[i]
			displayUnit(unitData, script.Parent["ViewportFrame" .. viewportFrameIndex])
		end
	end
	-- Inside the function displayPageUnits, after updating the visible viewport frames
	totalPages = calculateTotalPages()
	pager.Text = "Page " .. currentPage .. "/" .. totalPages
end

-- Function to handle scrolling to the next page
local function nextPage()
	if currentPage < totalPages then
		currentPage = currentPage + 1
		displayPageUnits(currentPage)
	end
	-- Make the cloned viewport frames visible
	for _, clonedViewportFrame in ipairs(clonedViewportFrames) do
		clonedViewportFrame.Visible = true
	end
	-- Set the scrolling frame's CanvasPosition to (0, 0)
	script.Parent.CanvasPosition = Vector2.new(0, 0)
end

-- Function to handle scrolling to the previous page
local function previousPage()
	if currentPage > 1 then
		currentPage = currentPage - 1
		displayPageUnits(currentPage)
	end
	-- Make the cloned viewport frames visible
	for _, clonedViewportFrame in ipairs(clonedViewportFrames) do
		clonedViewportFrame.Visible = false
	end
	-- Set the scrolling frame's CanvasPosition to (0, 0)
	script.Parent.CanvasPosition = Vector2.new(0, 0)
end


-- Event listener for the right arrow button to go to the next page
script.Parent.Parent.ScrollRightButton.MouseButton1Click:Connect(nextPage)

-- Event listener for the left arrow button to go to the previous page
script.Parent.Parent.ScrollLeftButton.MouseButton1Click:Connect(previousPage)

-- Display units on the initial page
displayPageUnits(currentPage)

-- Call the function to clone viewport frames
cloneViewportFrames()

local totalUnitCount = 0  -- Track the total count of units in the inventory

game.Players.LocalPlayer:WaitForChild("Inventory").ChildAdded:Connect(function(child)
	print(child.Name .. " added , value is " ..  child.Value)
	-- Increment the total unit count
	totalUnitCount = totalUnitCount + 1
	local function countUnitOccurrences(unitName)
		local count = 0
		local inventoryFolder = game.Players.LocalPlayer:WaitForChild("Inventory")
		for _, unit in ipairs(inventoryFolder:GetChildren()) do
			if unit.Name == unitName then
				count = count + 1
				displayUnit(child, script.Parent["ViewportFrame" .. #displayedUnits+1])
			end
		end
		-- Check if the total unit count is a multiple of 15
		if totalUnitCount % 15 == 0 then
			cloneViewportFrames()  -- Call the function to clone viewport frames
			print(totalUnitCount)
		end
		return count
	end

	local unitCount = countUnitOccurrences(child.Name)
	print(child.Name .. " count in inventory:", unitCount)
	-- Display the unit in the appropriate viewport frame
	for i = 1, unitCount do
		displayUnit(child, script.Parent["ViewportFrame" .. #displayedUnits+1])
	end
end)

I hope we can find a solution that is easy to understand and execute, because I do not wish to waste more time on something like an inventory that should be simple.