How do you make EgoMoose's Placement System 3D rather than 2D?

If you are not aware of EgoMoose’s amazing resource, you can check it out:

Either way, I’m interested in turning the existing placement system into 3D. For example, what math would I change with the grid calculation method? And should I change the target filter from the canvas? I have many questions and I would really like them to be answered. Hope to some great responses.

1 Like

Eliminate placement across an axis. Placement is just changes on a 3D axis (X, Y and Z), so prevent movement across one axis and that should about resolve it at a fundamental level (2D axis is usually X and Y).


As @EgoMoose mentions in that thread, if you take your time to step through the tutorial one idea at a time, you will understand how to go about answering your own questions and building your own version of this.

It already is 3D, including enough information to place on different sides of a part.

It’s not clear what your post means by 3D. Try changing CFrame Position values for X, Y, Z in @EgoMoose’s code. Set one axis value to 0 and see what happens. Now set it to another value or your own calculation for a new value and see what happens.

Set the Y axis component of the model positioning code equal to the Y axis component of Mouse.Hit for example.

1 Like

Well, his placement system uses Vector2 and I want to convert it to Vector3. How would I do that?

I think you might’ve meant to say it uses Vector3 and you want Vector2? If so, you can convert by constructing a Vector2 using the properties of the Vector3.

local vector3D =, 200, 200)
local vector2D =, vector3D.Y)

Your thread is coming off as vague so it’s becoming harder to understand what you want, namely what space you’re working in: interfaces or the Workspace? If it’s the Workspace, read my post again - you simply need to prevent movement across the depth axis.

Ok, so EgoMoose uses Vector2 to represent the grid space. I want to know how to use Vector3 to do that.

function Placement:CalcCanvas()
	local canvasSize = self.CanvasPart.Size

	-- want to create CFrame such that cf.lookVector == self.CanvasPart.CFrame.upVector
	-- do this by using object space and build the CFrame
	local back =, -1, 0)
	local top =, 0, -1)
	local right =, 0, 0)

	-- convert to world space
	local cf = self.CanvasPart.CFrame * CFrame.fromMatrix(-back*canvasSize/2, right, top, back)
	-- use object space vectors to find the width and height
	local size = * right).magnitude, (canvasSize * top).magnitude)

	return cf, size

That’s the surface width and height which is used for constraining to a surface. I dont understand what you’d need to convert to vector3?

Ooh, sorry, I completely misread the thread. I thought you wanted representation in 2D space, not that you were looking to convert this to 3D (whatever that means though).

I want users to be able to place multiple layers of objects, like walls.

To stack multiple layers of objects, you’ll need to pre-determine what the rules are. Do placed objects have to align themselves in any particular way? What is a valid position for placement, and what isn’t?

The canvas objects and the filter used by @EgoMoose provide convenient rules for placement constraints. If you use them, placement is restricted to those constraints.

To stack, you’ll need to detect that the activated placement position (where the mouse or touch tap hits) is the top surface (or valid upward facing surface) of another model (or part) that is allowed to be underneath the new placement.

So, at the time placement is requested by the user, run some additional checks to figure it out. After adding in the Y axis component as described above.

Something that’s gone unmentioned is that the code uses X and Y internally to represent a plane of placement, but acts upon the X and Z world axis externally. That may be a source of confusion for you. It also means that adding stacking placement requires a bit of refactoring.

Or for a hack, you could try adding a canvas object on top of each model that is placed …