How to snap an object to another and rotate like it's orientation

Hi Guys, so I’m trying to make a sandbox tycoon and I’m heavily inspired by Restaurant Tycoon 2 (by Ultraw) and I’m also trying to learn some features of it for my programming knowledge but I’m stuck with a part
(Sorry I can’t send the video because it’s having problem many timessss)
If you try to place an art object you will notice it snaps it to another wall and rotates according to it when I drag it and it also can’t go on the floor and will be just on the wall.

I just want to ask how can I achieve it ? I’m supposing I should use raycast. Thanks ! :smile:

First, you might not want to start with a super big project to begin with. I’d recommend starting with something small before making something more complex (e.g., a sandbox tycoon.)
Now, for the actual question. Yes, you would use raycasting. Raycasts return a value, Normal
The Normal value is the unit vector of the orientation of the face. An example would be if a cubic part was facing in the positive Z direction (0, 0, 1) and we raycasted onto the front of a part, Normal would be (0, 0, 1) A raycast that hit the back would be (0, 0, -1). Does this make sense? I can help you a little more if you need it.

You can use a raycast to detect the part the player is moused over. You can copy its orientation to the part you are placing, plus the offset in position. I strongly recommend you have an attachment somewhere on your placed part that defines where it sits on the target surface. The math to do this is quite annoying but basically you must solve the following:

Assume target is the part the player is placing on
Assume attach is the attachment mentioned
Assume primary is the primary part of the model being placed

Attach and primary both have a WorldCFrame (just CFrame for primary). You need a CFrame that transforms from the attach point to the primary, because you will be placing the model by moving the primary. Call this CFrame ppInverse:

ppInverse = attach.WorldCFrame:Inverse() * primary.CFrame

You now need the target CFrame at which to place the attachment:

targetCframe = target.CFrame - targetCFrame.Position + rayResult.Position

Now you need a CFrame that places the models primary part CFrame such that the attach CFrame is at targetCFrame:

pivotCFrame = targetCFrame * ppInverse
model:PivotTo(pivotCFrame)

As Sans mentioned, this is very complicated and you should start with something smaller, even a basic placement system that doesn’t account for rotation. If you wait maybe a week I can give you a working example of this as I’ve also had to make one of these.

You can also greatly simplify the problem by using a simpler placement system, such as one where you just click on a tile that pre-defines a position, or a system where you place something then drag it into place one axis at a time, like the studio position tool.

Yeah, I’m just like 2 years experienced and intermediate programmer and this is my first time I’m making a sandbox tycoon, so I’m trying to learn many more things before I should even start making it. But thanks for your answer !

Ok, I didn’t know.
You had no places on your profile (besides the starter place) so I thought you may have been new to Roblox and just looked through the documentation.
(Though, I probably should’ve realized through your knowledge of raycasting :smile:)

No problem it’s fine ! :smile: It’s just my alt I’m using because my main is under 13 by accident, but thanks for the answer !

Yeah, I’ll try for sure ! I’m learning things to make this game possible as when I came to development on Roblox, I learnt other languages earlier so I knew everything isn’t easy. So I know I need to work more to achieve this, but thanks for the answer ! :smiley: Also, if you wish, you can send me what you have made as you said so I can get an idea, I don’t have any hurry making this :slight_smile:

I think you guys misundertood what I meant. I’m not asking for a placement system guys, I’m asking like the art object snaps to the wall only and not the floor and after it snaps, it can’t go down the wall, how to achieve that ?

If you have the target object you are aligning to, you can snap the rotation to it by using the CFrame.fromMatrix method, inputting the normal and the normal’s cross with the RightVector as the parameters.

You can use a WeldConstraint between the art and the wall.

I’m not sure about your first problem, but about the second, you need to use a WeldConstraint to weld the art to the wall.

Ok, thanks but I want to understand that can’t we just do CFrame.new(pos_X, posY, pos_X + normal) ? As when I searched more about Surface Normal, they used this to align/rotate objects to the normal (I read that it’s just like LookVector though)

Because CFrame.new does positional values with these parameters. However, you can construct the whole CFrame yourself with all parameters including rotational values.

However, if you’re talking about CFrame.lookAt, you can do this with the method you described too.

Alr, thanks for the answer ! :slight_smile: I’ll do it