How do I make my building system snap on part surfaces and on a grid, like the classic Stamper Tool?
|If possible please write easy answers for me to understand when it comes to CFrame math! I'm still figuring out how it works. Thanks in advance.|
My goal here is to make a building system where I could snap objects to surfaces of other objects while still following a grid (like the Stamper Tool or something else similar.)
Currently I've only managed to make grid snapping (I deleted that part of the code.) Surface snap only works when I remove the grid snapping functionality and all the workarounds I could think of don't work correctly (or I'm probably just tired when I work with them).
What else can I do to make this happen?:
01 | local PlayerCont = game:GetService( "Players" ) |
02 | local Mouse = PlayerCont.LocalPlayer:GetMouse() |
03 | local PlacementCursor = Instance.new( "Part" , workspace) |
21 | PlacementCursor.Transparency = 0.8 |
22 | PlacementCursor.Anchored = true |
23 | PlacementCursor.CanCollide = false |
24 | PlacementCursor.CastShadow = false |
25 | PlacementCursor.Size = Vector 3. new( 4 , 4 , 4 ) |
26 | PlacementCursor.Material = "Neon" |
28 | Mouse.TargetFilter = PlacementCursor |
32 | function cmath.even(x, returnNum, custCheck) |
33 | local custN = custCheck or 1 |
37 | return (x % custN) = = 0 |
40 | function cmath.nearest(x, roundnum) |
41 | local rounding = roundnum or 1 |
42 | if typeof(x) = = "Vector3" then |
43 | local X, Y, Z = x.X, x.Y, x.Z |
44 | local rX, rY, rZ = cmath.even(X, true , rounding) / rounding, cmath.even(Y, true , rounding) / rounding, cmath.even(Z, true , rounding) / rounding |
47 | X = math.ceil(X / rounding) * rounding + (SnapByStuds/ 2 ) |
49 | X = math.floor(X / rounding) * rounding + (SnapByStuds/ 2 ) |
53 | Y = math.ceil(Y / rounding) * rounding + (SnapByStuds/ 2 ) |
55 | Y = math.floor(Y / rounding) * rounding + (SnapByStuds/ 2 ) |
59 | Z = math.ceil(Z / rounding) * rounding + (SnapByStuds/ 2 ) |
61 | Z = math.floor(Z / rounding) * rounding + (SnapByStuds/ 2 ) |
64 | return Vector 3. new(X, Y, Z) |
74 | function DisplayNewPosition() |
75 | local Normal = Vector 3. FromNormalId(Mouse.TargetSurface) |
76 | local Position = Mouse.Hit.p |
77 | local CursorCFrame = Mouse.Hit |
78 | local Anchor = Mouse.Target |
80 | if CursorCFrame ~ = nil and Anchor ~ = nil then |
81 | local ObjectHit = Anchor.CFrame |
82 | local ObjectSpace = Anchor.CFrame:ToObjectSpace(CFrame.new(Position)) * CFrame.Angles( 0 , 0 , 0 ) |
83 | local ObjectRotation = Anchor.CFrame - Anchor.CFrame.Position |
84 | local RotatedNormal = (ObjectRotation * Normal) * (PlacementCursor.Size / 2 ) |
86 | local FinalFormulation = (ObjectHit * ObjectSpace) + RotatedNormal |
88 | PlacementCursor.CFrame = FinalFormulation |
92 | function RequestAddition() |
96 | Mouse.Move:Connect(DisplayNewPosition) |
Thanks (again) in advance!