Random placement script issues

My code currently is

repeat
				place.PrimaryPart.Position = Vector3.new(math.random(minX, maxX), place.PrimaryPart.Size.Y / 2 + v.Size.Y / 2, math.random(minZ, maxZ))
				boxFrame, boxSize = place:GetBoundingBox() -- Get the part's bounding box location and size
				print(workspace:GetPartBoundsInBox(boxFrame, boxSize))
				print({place, v})
				task.wait()				
			until workspace:GetPartBoundsInBox(boxFrame, boxSize) == {v} or workspace:GetPartBoundsInBox(boxFrame, boxSize) == {place, v}

The outputs from both print statements are the same but for some reason it still repeats infinitely.

?

First, you still using the boxFrame, as I said you need to supply a new random one based on your base part. You should at least try those suggestions, otherwise its complex to progress on your topic.

Look I took a few minutes to build a random placement script that clones a model which has 3 parts, and place it in a random position of a baseplate, it avoids the parts to intersect with each other, it will retry until finding enough room to place the model, and it lands it on the baseplate, it will work for any model size nicely:

Well now my current code is

repeat
				testPos = Vector3.new(math.random(minX, maxX), place.PrimaryPart.Size.Y / 2 + v.Size.Y / 2, math.random(minZ, maxZ))
				boxFrame, boxSize = place:GetBoundingBox() -- Get the part's bounding box location and size
				print(workspace:GetPartBoundsInBox(testPos, boxSize))
				print({place, v})
				task.wait()				
			until workspace:GetPartBoundsInBox(testPos, boxSize) == {v} or workspace:GetPartBoundsInBox(boxFrame, boxSize) == {place, v} -- make that thing work later
			place.PrimaryPart.Position = testPos

And it just returns “Unable to cast Vector3 to CoordinateFrame”

The error is giving you all clues. You gave a Vector3 and the method requires a CFrame:

GetPartBoundsInBox Docu:

So, in this: :GetPartBoundsInBox(testPos, boxSize)
testPos needs to be a CFrame.
But your testPos is a testPos = Vector3.new(

Well then how would I turn it into one?

Just create a CFrame and instead of a Vector3:

Instead of:

testPos = Vector3.new(math.random(minX, maxX), place.PrimaryPart.Size.Y / 2 + v.Size.Y / 2, math.random(minZ, maxZ))

Do:

testPos = CFrame.new(math.random(minX, maxX), place.PrimaryPart.Size.Y / 2 + v.Size.Y / 2, math.random(minZ, maxZ))

Now it once again repeats infinitely, only this time the part doesn’t teleport around.

until workspace:GetPartBoundsInBox(testPos, boxSize) == {v} or workspace:GetPartBoundsInBox(boxFrame, boxSize) == {place, v} -- make that thing work later

And you fixed that line which you commented as “make that thing work later”?

Cause that line makes no sense to me.
I did it like this and it works as expected:

repeat
	-- CODE THAT GETS THE RANDOM COORDINATES
	
	-- CREATING THE CFRAME WITH THE RANDOM COORDS
	newRandomCFrame = CFrame.new(randomX, basePos.Y + baseSize.Y/2 + boxSize.Y/2, randomZ)
	
	-- MAX ATTEMPS
	attempts = attempts + 1
	
until #workspace:GetPartBoundsInBox(newRandomCFrame, boxSize, overlapParams) == 0 or attempts >= maxRetries

-- RESULTS
if attempts < maxRetries then
	model:PivotTo(newRandomCFrame)
	model.Parent = workspace.Folder
else
	warn("Failed to find a empty position after 10 retries")
end

Yeah I fixed that, the comment is from when I started working on the system and I forgot to remove it lol

Where did overlapParams come from?

You will use overlapParams as blacklist or whitelist in order the GetPartBoundsInBox exclude some parts inside the area that is checking. Like, you want to exclude the baseplate, otherwise it wont find free space if the baseplate is inside that area.

You can create your overlapParams like this:

	local overlapParams = OverlapParams.new()
	overlapParams.FilterDescendantsInstances = {baseplate}
	overlapParams.FilterType = Enum.RaycastFilterType.Exclude
	overlapParams.MaxParts = 10

Why does it have to be a local variable?

That doesnt matter, turn it into global if you need it as that. The thing, is that you can create the params in the script and then use it when your loop runs to check the specific area you need

I thought blacklist is depreceated

It is, that’s why I said Enum.RaycastFilterType.Exclude , Exclude not Blacklist

1 Like

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