Cloning not working

Hi, I’m trying to clone 5 skins and have them parented to a skins folder, however, it only cloned 1 and doesn’t clone the rest. Here is my script:

function SelectSkins()
	local rand = Random.new()
	local allSkins = game.ReplicatedStorage.AllSkins:GetChildren()
	local fiveRandomSkins = allSkins[rand:NextInteger(5,#allSkins)]
	
	return fiveRandomSkins
end

local chosenSkins = SelectSkins()

local clonedSkins = chosenSkins:Clone()
clonedSkins.Parent = game.ReplicatedStorage.Skins

NextInteger will return a single integer between 5 and #allSkins. You will only be getting receiving 1 skin, not 5. You can loop through all of the skips until you get 5 skins instead, something like

local function SelectSkins()
	local allSkins = game.ReplicatedStorage.AllSkins:GetChildren()
	local fiveRandomSkins = {}
	
	while #fiveRandomSkins < 5 do -- grab random skins until there are 5 chosen
		local newSkin = allSkins[math.random(#allSkins)] -- get a random skin
		for index, skin in pairs(fiveRandomSkins) do -- check for duplicated skin
			if newSkin == skin then
				continue -- return to top of loop
			end
		end
		table.insert(fiveRandomSkins, newSkin) -- add skin to list
	end
	
	return fiveRandomSkins
end

This will return a list of 5 random skins. Now, since you have a list instead of an object, you cant used Clone() on it. Instead, loop through the fiveRandomSkins list, cloning each one by one.

local chosenSkins = SelectSkins()
for index, skin in pairs(chosenSkins) do -- loop through all chosen skins
	skin:Clone().Parent = game.ReplicatedStorage.Skins -- add skin to `Skins`
end

Now, I can’t test any of this so let me know if it doesn’t work.

1 Like

Would you know how to detect duplicates?

What do you mean?

This section of code will ignore duplicated skins, so only unique skins should be added to the list.

It currently will choose 5 random ones however sometimes it will choose 2 of the same thing

That’s weird. Try debugging with a print statement after if newSkin == skin then to see if its a problem with the duplicate check or perhaps just some of the same skins in allSkins?

I added it and it created 3 of the same statements with three of the same skins

The statements are printing yet the duplicate skins are still being added? I don’t really know why that’s the case, but you can do this instead

	while #fiveRandomSkins < 5 do
		local newSkin = allSkins[math.random(#allSkins)] -- get a random skin
		local duplicate = false
		for index, skin in pairs(fiveRandomSkins) do -- check for duplicated skin
			if newSkin == skin then
				duplicate = true
			end
		end
		if not duplicate then
			table.insert(fiveRandomSkins, newSkin) -- add skin to list
		end
	end

Hopefully this works better.

1 Like

Works like a charm! I have a question, if you don’t mind, would you know how to make it so that the skins show up from least to greatest cost value? Each skin has a cost intvalue in them and I can’t get my head around on how to add that. Here is the function where it adds the skins if you need it:

function addSkins(data)
	for i, v in pairs(data) do
		local frame = createFrame(v.Name, v.Cost.Value, v, skins.Folder, "skin")
		if game.Players.LocalPlayer.SkinInventory:FindFirstChild(v.Name) then
			frame.Cost.Text = "Owned"
			frame.Button.Image = greenTick
		end
		
		if game.Players.LocalPlayer.equippedSkin.Value == v.Name then
			frame.Cost.Text = "Equipped"
			frame.Button.Image = greenTick
		end
		
		frame.Button.MouseButton1Click:Connect(function()
			local result = game.ReplicatedStorage.BuyItem:InvokeServer(v.Name, "skin")
			
			if result == "bought" then
				frame.Button.Image = greenTick
				frame.Cost.Text = "Owned"
				
			elseif result == "equipped" then

				
				for _, object in pairs(skins.Folder:GetChildren()) do
					if object:IsA("Frame") and object:FindFirstChild("Cost") then
						if game.Players.LocalPlayer.SkinInventory:FindFirstChild(object.Name) then
							object.Cost.Text = "Owned"
						end
					end
				end
				frame.Button.Image = greenTick
				frame.Cost.Text = "Equipped"
			end

		end)
	end
end
1 Like

EDIT: Hey there. In case this thread is seen in the future, I want to update this post because wow the sorting method I gave was complete garbage. I messages OP with a better sorting algorithm as to not reopen a dead thread, but I figured I should post the better method here. The original post can still be seen in it’s full, unaltered glory in the selection tab conveniently labeled “Original Post”.

Original Post

There may be a better way about this, but this is what I came up with. It’s probably over complicating it, but its late and I’m tired lol.

local function findCheapestSkin(skins) -- list of skins
	local min = math.huge
	local cheapestSkin = {}
	for index, skin in pairs(skins) do
		if skin.IntValue.Value < min then -- check skin cost against current min
			min = skin.IntValue.Value -- set new min
			cheapestSkin = {index, skin}
		end
	end
	return unpack(cheapestSkin)
end

local function orderSkinList(skins)
	local orderedList = {}
	
	while #orderedList < 5 do
		local index, skin = findCheapestSkin(skins) -- get the cheapest skin
		table.remove(skins, index) -- remove skin from main list
		table.insert(orderedList, skin) -- add skin to orderedlist
	end
	
	return orderedList
end

local chosenSkins = SelectSkins() -- random list of the 5 chosen skins
local orderedList = orderSkinList(chosenSkins) -- actual ordered list (least to greatest)

Again, I can’t test it so I’m just hoping it works.

This time I’m using an actually established sorting algorithm, bubble sort. This is by no means the most efficient algorithm, but for a small list of 5 it won’t really matter. The code I give here is just sorting a table of integers.

-- sort function
local function sortList(list)
	local success
	repeat
		success = true -- come into the loop assuming list is ordered. ("innocent until provent guilty", or whatever)
		for i = 1, #list - 1 do
			-- this is where I compare the values (costs of skins). Change to work for you.
			if list[i] > list[i+1] then
				success = false -- if you need to swap two indexes, then the list isn't ordered.
				local store = list[i]
				list[i] = list[i+1]
				list[i+1] = store
			end
		end
	until success -- until list is sorted
	return list
end


-- create random list
local randomList = {}
for i = 1, 5 do
	table.insert(randomList, math.random(9))
end
print("Unsorted list: ", unpack(randomList))

-- get a sorted list
local sortedList = sortList(randomList)
print("Sorted list: ", unpack(sortedList))
Sample output >>>
Unsorted list:  4 9 3 2 8
Sorted list:  2 3 4 8 9

Should i put this outside of the addskins function? Thank you so much! I’d never be able to think of that!

Yes, these are intended as different functions. You can probably put the code from findCheapestSkin into orderSkinList if you want, though.

Should I put this before the select skins function or after…? I’m receiving an error to which it says IntValue is not a member of the Model

That’s because I didn’t know what you named the IntValue, so I just simply used IntValue. You will need to change the line commented with “set new min” in findCheapestSkin to reference the actual cost Intvalue

Hmm, still getting this error: 23:19:17.723 - IntValue is not a valid member of Model

Again, I don’t know where your IntValue is placed in reference to the skin, or what it is named. You will need to change the line min = skin.IntValue.Value -- set new min to properly reference the skin’s IntValue.

That’s what I did though. Would you like to look at the actual game?

UPDATE: Fixed

hmm still doesn’t do what it’s supposed to do.

1 Like