I am not really experienced with a game like this, but I thought of a simple algorithm that could help you achieve your goal. I am not sure that it’s the best way though.
Alright, so imagine you have this and you want to get the “insides”
What I thought of is that you are going to go through each row and check the farthest left and farthest right positions (marked red below). I assigned a number to each row.
So now we are simply going through each row and see if there are any empty parts between them.
We can see there are 2 parts between the red parts, these are part of the border. Whether you want to include this in your “empty parts” collection, it’s up to you, but I am going to assume you do want this. We will be coloring every “empty part” green.
Now we have this. We can repeat this for the next row and we will get all our empty spaces.
Problem with this is that it will not work with shapes like this, because it would also get the spaces outside of the shape (marked dark green)
So perhaps you want to go for a different approach that will get the red parts like so
But I wouldn’t be sure how to do that.
I am just giving you ideas cause I am not certain on how to achieve this in the best way possible.
Here’s an idea. Run a “tracker” through across each layer. I’m using a sort of grid system here with tiles of 4 and I hope you are using the same or I don’t think this works. I keep track whether I’m in an empty zone or not.
To calculate a random position from these parts you’d do something alone the lines of:
local currentTile
local parts = workspace.Parts
local touchTable = {false,false} -- {previousPart, currentPart}
local emptyLines = 1
local possibleTiles = 0
local top = -1000
for i,v in parts:GetChildren() do
if v.Position.X > top then
top = v.Position.X
end
end
local bottom = 1000
for i,v in parts:GetChildren() do
if v.Position.X < bottom then
bottom = v.Position.X
end
end
local left = 1000
for i,v in parts:GetChildren() do
if v.Position.Z < left then
left = v.Position.Z
end
end
local right = -1000
for i,v in parts:GetChildren() do
if v.Position.Z > right then
right = v.Position.Z
end
end
local function newPart(pos)
local newPart = Instance.new("Part")
newPart.Anchored = true
newPart.Size = Vector3.new(4,0.25,4)
newPart.Position = pos
newPart.Parent = workspace
if newPart:GetTouchingParts()[1] ~= nil then
touchTable[2] = true
else
touchTable[2] = false
end
currentTile = newPart
end
for i = top-4,bottom+4,-4 do
emptyLines = 1
for i2 = left-8,right+8,4 do
touchTable[1] = touchTable[2]
newPart(Vector3.new(i,0.25,i2))
if not touchTable[2] and touchTable[1] then
emptyLines += 1
end
if not touchTable[2] and emptyLines % 2 == 0 then
possibleTiles += 1
print(possibleTiles)
currentTile.Color = Color3.fromRGB(28, 12, 255)
end
wait()
end
end
print(possibleTiles)
I think Azartics idea is easiest and most simple. I think making a pre-made grid of parts in your areas and doing his code is best.
heres a code sample I made from his code which can get a random position inside one of the areas in your pic
local tilesfolder = workspace.TilesSection1
local tiles = tilesfolder:GetChildren()
function getrandompos()
local randomtile = tiles[math.random(1, #tiles)]
local newsize = randomtile.Size/2
local randomX = math.random(-newsize.X, newsize.X)
local randomZ = math.random(-newsize.Z,newsize.Z)
local randomPos = Vector3.new(randomX, 0, randomZ)
local finalrandomposition = randomtile.Position+randomPos
return finalrandomposition
end
Well it looks like the parts in the pictures you sent at 2x2x2 cubes. In the actual game, do the players take over (invisible) tiles, (“grid system”), or do the players have complete free realm of which areas they can occupy. ie. how does your game work for taking over areas?
Ouch, this just made everything really complicated. Here’s an idea
First consider the point the player leaves to the points the player arrives
You’d then need to calculate whether the player has travelled in a clockwise, or
anti-clockwise direction
From here can pick any random point on the line the user has generated, and pick a
random point along this line. (I don’t know how your system works, so I’m not sure how hard
all of this is to implement)
With your random point chosen, you can then fire a raycast to the normal of the direction of the line
If the player travelled clockwise you can fire the raycast to the right of the normal, and for anti-clockwise fire the raycast to the left on the normal.
Here’s an example with clockwise rotatation by the player, with some possible raycasts shown
In reality the raycast could be created anywhere along the line
With the raycast fired, it would stop when it meets the point on the same line generated by the user.
Will this work? No clue lol, it’s pretty complicated
There are a lot of random shapes the player can create, so it’s hard to visualize
I guess if the raycast returns nil on the touch you could generate a new random raycast until you get a hit