I'm working on a "Random Part Placer", my idea is to do a random vector3(x,y,z) (limited of course to the size of the map), the problem is that the random generator is not that random and parts are being placed on the same position.
If anyone can help me with a simple code, that would be great. Btw i'm also working on it and if i come up with something i will post it here for everyone.
Thanks for read
This is a good question, and I'm going to provide my solution. My solution might not be the best, and if anyone reading this has a better solution, I would like to see it.
I would suggest storing the values inside a table as you create them, and check using a function if the new random Vector3 is close to that. If it is, create a new random vector.
First, I'm going to create a function that returns a random vector.
local MaxSizeX = 200 local MaxSizeY = 50 local MaxSizeZ = 200 local function RandomVector3() return Vector3.new( math.random(-MaxSizeX, MaxSizeX), math.random(0, MaxSizeY), math.random(-MaxSizeZ, MaxSizeZ), ) end
You could construct this however you want to fit your needs.
Next I would make a function that returns a part.
local PartSize = Vector3.new(2,2,2) local function CreatePart() local part = Instance.new("Part") part.Size = PartSize part.Anchored = true part.BrickColor = BrickColor.Random() return part end
Now I'm going to create the table.
local PastPositions = {}
This will be used to store the positions.
Now we can create the main action of the script. A loop which continuously creates parts.
local MaxSizeX = 200 local MaxSizeY = 50 local MaxSizeZ = 200 local PartSize = Vector3.new(2,2,2) local PastPositions = {} local function RandomVector3() return Vector3.new( math.random(-MaxSizeX, MaxSizeX), math.random(0, MaxSizeY), math.random(-MaxSizeZ, MaxSizeZ), ) end local function CreatePart() local part = Instance.new("Part") part.Size = PartSize part.Anchored = true part.BrickColor = BrickColor.Random() return part end while true do local part = CreatePart() part.CFrame = CFrame.new(RandomVector3()) part.Parent = workspace wait() end
This creates the parts in workspace. This is probably about what you have.
Now we need to save the part's Vector3 inside the tables when it's created.
while true do local part = CreatePart() local NewVector = RandomVector3() PastPositions[#PastPositions+1] = NewVector part.CFrame = CFrame.new(RandomVector3()) part.Parent = workspace wait() end
Now we don't want to save the new Position if the Position already exists. So now we need to create a function that checks if the positions already exists in the table.
--// Returns true if vector is already in table, else returns false. local function CheckTableForPosition(TheVector) for _, Vectors in pairs(PastPositions) do if Vectors == TheVector then return true end end return false end
Now we can combine this with out main code.
while true do local part = CreatePart() local NewVector = RandomVector3() while CheckTableForPosition(NewVector) do NewVector = RandomVector3() end PastPositions[#PastPositions+1] = NewVector part.CFrame = CFrame.new(NewVector) part.Parent = workspace wait() end
Now this will make sure it doesn't make a part with the EXACT same position, but we probably want a little space as well. The changes are below.
--// This is the closest the parts can be together. local ClosestDistance = 5 --// Returns true if vector is already in table, else returns false. local function CheckTableForPosition(TheVector) for _, Vectors in pairs(PastPositions) do local magnitude = (Vectors - TheVector).Magnitude if magnitude < ClosestDistance then return true end end return false end
This uses magnitude to check how close the vectors are.
My final example script would look as such,
local MaxSizeX = 200 local MaxSizeY = 50 local MaxSizeZ = 200 local PartSize = Vector3.new(2,2,2) local PastPositions = {} local ClosestDistance = 5 --// Returns true if vector is already in table, else returns false. local function CheckTableForPosition(TheVector) for _, Vectors in pairs(PastPositions) do local magnitude = (Vectors - TheVector).Magnitude if magnitude <= ClosestDistance then return true end end return false end local function RandomVector3() return Vector3.new( math.random(-MaxSizeX, MaxSizeX), math.random(0, MaxSizeY), math.random(-MaxSizeZ, MaxSizeZ), ) end local function CreatePart() local part = Instance.new("Part") part.Size = PartSize part.Anchored = true part.BrickColor = BrickColor.Random() return part end while true do local part = CreatePart() local NewVector = RandomVector3() while CheckTableForPosition(NewVector) do NewVector = RandomVector3() end PastPositions[#PastPositions+1] = NewVector part.CFrame = CFrame.new(NewVector) part.Parent = workspace wait() end
This is not meant to be copy and pasted. This is only a walkthrough of the thought process I went through to come up with a working solution.
There are probably errors, but the main idea of the script should do fine.
Thanks for reading!
function init(xpos, zpos) local Block = Instance.new("Part", workspace) --[Declaramos la pieza]-- Block.Name = "Block" Block.Parent = workspace Block.Anchored = true Block.CanCollide = false game.Workspace.Block.Size = Vector3.new(10, 0.5, 10) --[Forma plana]-- game.Workspace.Block.Position = Vector3.new(3, 0.5, 3) --[PosiciĆ³n]-- local Amount = Instance.new("IntValue", Block) --[Declaramos las Reservas]-- Amount.Value = math.random(1000, 100000) end init(xpos, zpos)
That's what i came up with, i lacked the randomizer and something to store the occupied areas. Thanks for the answer