Placement system with multiple part surfaces and object bounds

Hello All!

I am currently working on a placement system for a game of mine. The catch is the placement will take place across multiple surfaces, or floors. Normally this isn’t a challenge at all.

However, I need to make sure the object doesn’t go outside of the placement region. I want the model to stop moving if it is touching the edge of the place-able region.

The code for determining the grid position.

CalcCanvas function

local canvasSize = canvas.Size

local back = -canvas.CFrame.lookVector
local top = canvas.CFrame.upVector
local right = canvas.CFrame.rightVector

local cf = canvas.CFrame * CFrame.fromMatrix(-back*canvasSize/2, right, top, back)

local size = Vector2.new((canvasSize * right).magnitude, (canvasSize * top).magnitude)

return cf, size

Function bound to runService:RenderStepped

	local modelSize = CFrame.fromEulerAnglesYXZ(0, rotation, 0) * currentObject.PrimaryPart.Size
	modelSize = Vector3.new(math.abs(modelSize.x), math.abs(modelSize.y), math.abs(modelSize.z))
		
	local cf, size = placementService:CalcCanvas(mouse.Target)
		
	local lpos = cf:pointToObjectSpace(mouse.Hit.Position);
	-- the max bounds the model can be from the surface's center
	local size2 = (size - Vector2.new(modelSize.x, modelSize.z))/2
		
	x = math.sign(x)*((math.abs(x) - math.abs(x) % 1) + (mouse.Target.Size.x % 1))
	z = math.sign(z)*((math.abs(z) - math.abs(z) % 1) + (mouse.Target.Size.z % 1))
		
	currentObject:SetPrimaryPartCFrame(CFrame.new(x,y+1.25,z) * CFrame.Angles(0, rotation, 0))

I believe this is called a WorldBoundingBox. I know how to accomplish this with a normal rectangle or square, but with two surfaces I don’t want an awkward transition when dragging the model between them. I have already checked out this article, however I’m having a hard time implementing his system with mine. (Two completely different systems). Thanks if anyone can help!

1 Like

When I was experimenting with grids, the way I solved this problem was like so:

  1. When creating/initializing the grid: find all the cells which are invalid and mark them as so. (Or find all cells which are valid, and assume everything else is invalid)
  2. Whenever the user moves their mouse, check all the cells in which the selected item is in.
  3. If a cell is marked invalid, the item can’t be placed. If all cells are valid and the user places the item, mark those occupant cells as invalid.

As long as you have a decent grid setup, this should be pretty simple. The hardest part for me was figuring out the logic to find the cells contained within an item.

Here is the place I was playing around with grids. You can see that if the slope of the terrain is too steep, the object becomes unplaceable. I never finished it, so it’s possible to place multiple objects into each other, but it would be relatively simple for me to add it in.

1 Like

That’s a really cool system! My grid system is just a simple math equation paired with a grid texture. I edited the main thread to show the code.

If you’re only placing the model by locking it to a set offset, I would recommend that you remake your code into a full-fledged grid/cell format. This will give you much more control over how your objects are placed.

In your current system, it’s incredibly convoluted/sketchy to “block off” certain areas like in the picture. If you’re having trouble finding ways to create a full grid, the place I linked is uncopylocked and you could take a look at that (it’s messy code though, so watch out). I’d also recommend looking at https://www.redblobgames.com/ which has some good articles about understanding grids and graphs.

If you just want a stick with your current system, though, you could size a Region3 over the area in which your item is, and then find any parts in that region3 not part of the item.

1 Like