Get random position but with blacklisted areas

Sorry if the name of this topic is off, I wasn’t sure what to call it.

Basically, I’m trying to get a way to get a random position within a block but with areas that cannot be chosen, here’s an example:

RobloxScreenShot20220803_204840091 (3)

Green is the main area, red is the “blacklisted” areas that it cannot choose any positions within

How would I do this?

Few ways you could do this, I would Raycast from above using a random decider on the X + Y positions, and then raycasting down, but adding the red parts as blacklisted parts.

I would then run it until RaycastResult returns a value.

There might be a better way, though I’m unsure.

1 Like

I don’t see how this would work, I’m not trying to get any parts, I’m just trying to get random positions.

I’m using the term blacklisted areas because I want there be certain areas that it can’t randomly choose within (im using the red areas as an example in my original image)

1 Like

Here’s an example of something I just whipped up -

local function Raycast(GREENPART, REDPART_FOLDER)

	local X,Z = Random.new():NextNumber(GREENPART.Position.X-(GREENPART.Size.X/2), GREENPART.Position.X+(GREENPART.Size.X/2)), Random.new():NextNumber(GREENPART.Position.Z-(GREENPART.Size.X/2), GREENPART.Position.Z+(GREENPART.Size.Z/2))

	local RaycastResult = workspace:Raycast(Vector3.new(X, GREENPART.Position.Y + 10, Z), Vector3.new(0, -100, 0)*500)
	if RaycastResult then
		if not RaycastResult.Instance:IsDescendantOf(REDPART_FOLDER) then
			return RaycastResult.Position
		else
			return Raycast(GREENPART, REDPART_FOLDER)
		end
	end
end

while true do
	local Part = Instance.new("Part")
	Part.Anchored = true
	Part.Size = Vector3.new(1, 1, 1)
	Part.Parent = workspace
	Part.Position = Raycast(workspace.Part, workspace.Folder)
	task.wait(0.1)
end

1 Like

I like this idea, although instead of raycasting, I decided to just loop through all the blacklisted areas and check if the chosen position is within them. I’m planning on using this many times per heartbeat so raycasts felt unnecessary.

Here’s my code for getting a random position:


local function IsPositionInSidePart(X,Z,part) -- I only need to check the x and z
	local Position, Size = part.Position, part.Size
	local InX, InZ = (X < Position.X + Size.X/2 and X > Position.X - Size.X/2), (Z < Position.Z + Size.Z/2 and Z > Position.Z - Size.Z/2)
	return (InX and InZ)
end

local function GetRandomPosition()	
	local ChosenPosition = nil	
	repeat
		local Position = Main.Position + Vector3.new( -- Main is the green part in the picture. This is getting a random position within the green
			(math.random() - 0.5) * Main.Size.X,
			0,
			(math.random() - 0.5) * Main.Size.Z)
		local Safe = true
		for _, Part in pairs(BlacklistedAreas) do -- loop through all the blacklisted areas
			if IsPositionInSidePart(Position.X, Position.Z, Part) then -- if the position is within the blacklisted part
				Safe = false
				break
			end
		end	
		if Safe then
			ChosenPosition = Position
		end
	until ChosenPosition ~= nil	
	return ChosenPosition
end
1 Like