Object Snapping Build System

Looking to expand my building system into something a little more complex. Currently, models can freely be moved, rotated, and placed which also results in models becoming messy and unaligned. I’d like to create a system that will look for nearby models, and if they have an area to snap to, snap the position and rotation of the object being placed to the snap position.

As much as i’d like to create a system like this, I have no ideas on how to accomplish it. If anyone could provide a basis of ideas on how I could accomplish this, PLEASE let me know!

If anyone’s lost on my question, think of it as a Rust styled placement system.

15 Likes

I’m not going to pretend I am an expert, but One way you could go about this is having a table of variables with the X and Y positions of each placed object. So when the mouse hovers over, say X = 4.172364 (rando number), the script will ask "Is this mouse within .5 of X = 5 (or other table data).

To do this I picture you needing a few variables. One for a table of X, another for Y, and two more for the X and Y of the mouse placing the furniture. Hope this at least gave you an idea! :stuck_out_tongue:

To snap the position, lets say you wanted it to snap to the nearest 8 studs. You would do

local position = Vector3.new(math.floor(script.Parent.Position.X/8),math.floor(script.Parent.Position.Y/8),math.floor(script.Parent.Position.Z/8)))
2 Likes

That could possibly work :grinning:

1 Like

I appreciate your help, but i’m asking about snapping the position to any objects near rather than just forcing the entire system to a certain amount of studs at all times.

I have actually made a rust styled building system before and I think this should help you out.

So the way I did it was by using Attachments (You could use Vector3Values too but Attachments are easier to visualize and you wouldn’t need as many Attachments as you would Vector3Values). I would make an attachment for every position on a part I wanted the game to snap building objects to. So for example in Rust you can build floors and stuff. I would make an attachment on each side of the floor so that other floors could snap to them and I would also make attachments on the top of the floor on all 4 sides so that walls could snap to the floor. Just change the positions of the attachments until they are in the spot you want the building objects to snap to


Each of those attachments is a place that another building object can snap to. Don’t forget that you also need to put Attachments into the other building object too like Walls so when you are snapping parts the game knows what position on each part it should snap to. Also make sure the attachment is rotated the way you want the snapped object to be rotated

Next you need to name the Attachments based on what building object can snap to it. For example the attachments on the top of the floor can only snap to Walls/door/windows etc. so what I did when I was making the system was name them “WallSnapAttachment”. The Attachments on the sides of the floor I named “FloorSnapAttachment”

Now for the scripting part of the system. The way it should work is when the player’s mouse hovers over a building object, (The floor in this case) you need to loop through all of the attachments that are inside the building object. If the attachment is named appropriately (WallAttachment when placing a wall etc.) then you need to find out which attachment is closest to the mouse position.

Once you find the closest attachment you need to actually snap the parts together so that the attachments in the two parts end up in the same position.

Here is some basic cframe code that should give you an idea of how to do that. You will probably have to modify it at some point but for this scenario with the floors and walls it should work fine. In this code I am assuming we are snapping the Wall to the floor

local floor = --wherever the floor is
local wall = --wherever wall is

--Here we are moving the center of the wall to the snap position on the floor
local wallCframe = floor.CFrame *CFrame.new(floor.WallAttachment.Position)

--Here we are moving the wall so that the bottom of the wall will be resting on the floor
wallCframe = wallCframe *CFrame.new(-wall.FloorAttachment.Position)

--Now we just rotate the wall so it lines up with the edge of the floor
wallCframe = wallCframe *CFrame.Angles(0, math.rad(floor.WallAttachment.Orientation.Y), 0)

--Now just set the CFrame of the wall
wall.CFrame = wallCframe

I hope this helps and you were able to understand what I was trying to say, I’m not the best writer so I may explain things in a confusing way sometimes, just let me know and ill try to clarify anything you don’t understand

30 Likes

Thanks!!! It was a very good explanation that so far hasn’t given me any troubles, and honestly I didn’t know attachments were THAT handy!

1 Like

hey, i was wondering how i could use this on the base. Like make them snap and put them in the correct orientation?