I’m making a building game. Not gonna tell you what it is cuz it’s a suprise.
But I don’t understand how I can make the mouse position allign to a surface even when its on an empty space or when you wan’t to drag a furniture in certain games in a certain level, the furniture is like flying.
I see this on multiple things, Retail Tycoon 2, Theme Park Tycoon, even Lua Draggers.
I’m not good at explaining so I will just show you the examples:
Retail Tycoon 2:
Theme Park Tycoon:
Lua Debuggers:
I wan’t to achieve this without creating any new invisible BaseParts like using math.
I would be glad and embarrased if there is a simple solution to this.
You first have to guess what surface the player is trying to align with, usually you can assume its the last surface the part was placed on and that feels pretty good to control. Then, instead of raycasting, you calculate how long the mouse ray would have to be to touch this surface if it were extended to an infinite plane. To do this, find the distance between the start of the mouse ray (the camera) to the plane, call it D. Then, take the dot of the ray direction with the surface normal and call it U. Multiplying the length of the mouse ray so that U equals D will mean that the ray touches the plane (because of the laws of similar triangles), so now you just need to divide D by U to find out the value you need to scale the ray by.
If you are looking at an infinite plane, as long as you aren’t looking away, there is exactly one length of that looking vector which will touch the plane. The math above is for finding that multiplier.
Just to put @azqjanna‘a absolutely correct answer into more specific code terms:
We need to pick a plane (in the geometry sense not the airplane sense)—defined by a point and a normal vector.
Let’s pick our point p as the initial point the player clicks. Let’s pick our normal vector n as the normal of the face they clicked on. You can get these by raycasting with the mouse UnitRay
Figure out how far from the plane you are, d, with a dot product: local d = (unitRay.Origin - p):Dot(n)
Figure out how long the mouse ray is in the component of the normal: local u = -unitRay.Direction:Dot(n)
Scale the mouse ray by the ratio: local positionOnPlane = unitRay.Origin + unitRay.Direction * d / u
If that ratio d / u is negative, the player is facing away from the plane.
If you found this helpful, give the answer mark to @azqjanna since I just reworded what they said
Alright it worked as intended. Thank you @azqjanna and @nicemike40 for this method. I managed to make the ball fly while alligning on the surface. I did do some tweaking to get it working without raycasting.