Randomizing Model Based on Rarity.Value?

Seed and PickItem would ideally be defined outside of the ipairs loops
The PickItem function picks a string, not an Instance, so it cannot be Cloned or anything like that. You need to define the actual Instance with the assistance of the PickItem function

for example:

local ItemName = PickItem(Items)

local ItemModel = models[ItemName]:Clone()

-- do other stuff
1 Like

Thank you, this is starting to make more sense!

However, I’m getting an output error:

ServerScriptService.OtherScripts.ObjectDisplayScript:50: attempt to index nil with ‘Soul Seeker II’ - Server - ObjectDisplayScript:50

On this line:

local ItemModel = models[ItemName]:Clone()

Here’s the revised script:

local replicatedStorage = game:GetService("ReplicatedStorage")
local shopFolder = replicatedStorage:WaitForChild("Shop")
local workspace = game:GetService("Workspace")

-- Define the items and their rarities
local Items = {
	Crate = 30,
	["Beast Sense I"] = 15,
	["Soul Seeker I"] = 15,
	["Loot Finder I"] = 20,
	["Stealth I"] = 20,
	["Beast Sense II"] = 10,
	["Soul Seeker II"] = 10,
	["Loot Finder II"] = 10,
	["Stealth II"] = 10,
	["Soul Seeker III"] = 5,
	["Loot Finder III"] = 5,
	["Beast Sense III"] = 5,
	["Stealth III"] = 5,
}

local Seed = Random.new(tick())

local function PickItem(RarityList: {[string]: number}): string
	local Num = Seed:NextNumber(0, 100)
	local Int = 0
	for Item, Chance in pairs(Items) do
		Int += Chance
		if Num <= Int then
			return  Item
		end
	end
end

local ChosenItem = PickItem(Items)
print(ChosenItem) -- 66% chance to be Crate, 33% chance to be Stealth, 1% chance to be Loot Finder

-- Find all the SpecialDisplay1 objects in the workspace
local specialDisplays = workspace:GetDescendants()
for _, obj in ipairs(specialDisplays) do
	if obj.Name == "SpecialDisplay" then
		-- Find all the ObjectDisplay children of each SpecialDisplay1 object
		local objectDisplays = obj:GetDescendants()
		for _, child in ipairs(objectDisplays) do
			if child.Name == "ObjectDisplay" then
				-- Spawn a random model for each ObjectDisplay child
				local function spawnRandomModel()
					-- Select a random rarity level first
					local ItemName = PickItem(Items)
					local ItemModel = models[ItemName]:Clone()

					local randomModel = shopFolder:FindFirstChild(ItemName)
					if randomModel == nil then
						print("Model not found for item "..ItemName..".")
						return
					end
					
					local clonedModel = randomModel:Clone()

					-- Find the root part of the cloned model
					local rootPart = clonedModel.PrimaryPart.CFrame.Position

					-- Calculate the offset between the root part and the ObjectDisplay child
					local offset = child.Position - rootPart

					-- Parent the cloned model to the ObjectDisplay child and move it to the correct position
					clonedModel.Parent = child
					clonedModel:SetPrimaryPartCFrame(CFrame.new(child.Position)) --+ offset))
				end

				-- Spawn a random model immediately for each ObjectDisplay child
				spawnRandomModel()

				-- Spawn a new random model for each ObjectDisplay child every 30 minutes
				--while true do
				--      wait(30 * 60)
				--      spawnRandomModel()
				--  end
			end
		end
	end
end

models should point to the container that holds your instances that you want to have cloned

1 Like

Thank you! So it would be:

local ItemModel = shopfolder[ItemName]:Clone()

I’m assuming!

yes! however, your FindFirstChild() check is nice, so what you can do to add onto it:

local randomModel = shopFolder:FindFirstChild(ItemName)
if randomModel == nil then
	print("Model not found for item "..ItemName..".")
	return
else
	modelClone = RandomModel:Clone()
	-- do rest of code here with modelClone
end
1 Like