Parts shuffling, but does not maintain original shape

  1. What do you want to achieve? Keep it simple and clear!
    I want parts to shuffle while maintaining their original positions

  2. What is the issue? Include screenshots / videos if possible!
    The parts do not appear as if they were in their original positions. They’ll mostly overlap other parts or there will be a missing spot when they’re shuffled.
    Expected (after shuffle):

What actually happens (dunno if the video loads or not):

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I tried parenting a part to a position waypoint in-game, however I face the same issue or all parts tween at once,

Main code:

local TweenService = game:GetService("TweenService")

local keys = workspace:WaitForChild("keys")
local camPos = workspace:WaitForChild("camPos")
local camera = workspace.CurrentCamera

local positions = keys:WaitForChild("pos")

local lastPosition

function getRandomKey()
	local children = keys:GetChildren()
	local randKey = children[math.random(1, #children)]
	return randKey
end

function move(key)
	local positionsC = positions:GetChildren()
	local rand = positionsC[math.random(1, #positionsC)]
	if rand == lastPosition and lastPosition ~= nil then
		return move(key)
	else
		for i, keyItem in pairs(keys:GetChildren()) do
			if keyItem:IsA("Folder") == false then
				if (keyItem.Position - rand.Position).Magnitude < 1 then
					print("There's a key in that position")
				else
					lastPosition = rand
					TweenService:Create(key, TweenInfo.new(0.2), {Position = rand.Position}):Play()
				end
			end
		end
	end
end


function FOCUS()
	camera.CameraType = Enum.CameraType.Scriptable
	camera.CFrame = camPos.CFrame
	task.wait(3)
	for i = 1, 20, 1 do
		task.spawn(function()
			for i, k in pairs(keys:GetChildren()) do
				if k.Name ~= "pos" then
					move(k)
				end
			end
		end)
		task.wait(0.2)
	end
end

repeat task.wait() until game:IsLoaded() == true

FOCUS()
1 Like

To do this you need a table with all the original positions that always stays the same and another table used for the positions remaining. Basically what I did was whenever the shuffle function is runned an identical table to the original position table is created and stores all the positions remaining. Since it’s a cloned table, not actually the original, it can be tampered how much we want. In this case we want to get rid of the values so we don’t use them again.

Here is how I did it

local TweenService = game:GetService("TweenService")

local keys = workspace:WaitForChild("keys")
local camPos = workspace:WaitForChild("camPos",1)
local camera = workspace.CurrentCamera

local positions = {} -- all the possible positions
	
for _, v in pairs(keys:GetChildren()) do
	if v:IsA("BasePart") then
		table.insert(positions,v.Position)
	end
end

function getRandomKey()
	local children = keys:GetChildren()
	local randKey = children[math.random(1, #children)]
	return randKey
end

function shuffle()
	local freePositions = table.clone(positions) -- table for the positions left
	
	for i, k in pairs(keys:GetChildren()) do -- for every key
		local r = math.random(1, #freePositions)
		local position = freePositions[r] -- random position out of the free ones
		
		TweenService:Create(k, TweenInfo.new(0.2), {Position = position}):Play()
		table.remove(freePositions,r) -- remove used position
	end
end

function FOCUS()
	camera.CameraType = Enum.CameraType.Scriptable
	camera.CFrame = camPos.CFrame
	
	task.wait(3)
	for i = 1, 20 do
		shuffle()
		task.wait(.2)
	end
end

FOCUS()

Thank you so much! I replaced my local script with the one you provided me and it works like a charm

However, since the script i provided in my post is outdated, here is the new one with the code you gave in case others want to use it:

local TweenService = game:GetService("TweenService")

local keys = workspace:WaitForChild("keys")
local camPos = keys:WaitForChild("misc"):WaitForChild("camPos",1)
local camera = workspace.CurrentCamera

local positions = {} -- all the possible positions

for _, v in pairs(keys:GetChildren()) do
	if v:IsA("BasePart") then
		table.insert(positions,v.Position)
	end
end

function getRandomKey()
	local children = keys:GetChildren()
	local randKey = children[math.random(1, #children)]
	return randKey
end

function shuffle()
	local freePositions = table.clone(positions) -- table for the positions left

	for i, k in pairs(keys:GetChildren()) do -- for every key
		if k:IsA("Folder") == false then
			local r = math.random(1, #freePositions)
			local position = freePositions[r] -- random position out of the free ones

			TweenService:Create(k, TweenInfo.new(0.2), {Position = position}):Play()
			table.remove(freePositions,r) -- remove used position
		end
	end
end

function FOCUS()
	camera.CameraType = Enum.CameraType.Scriptable
	camera.CFrame = camPos.CFrame
	task.wait(3)
	for i = 1, 20 do
		shuffle()
		task.wait(.2)
	end
end

FOCUS()

Again thank you so much for the help! Much appreciated

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.