You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? Keep it simple and clear!
I am trying to snap the item to other parts. Like the placement system in “Build A Boat For Treasure”, where it can rotate and still work.
What is the issue? Include screenshots / videos if possible!
It kind of works but it doesn’t really work that well. (I don’t know how to add videos or screenshots)
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
This is the original code (Did not work with rotations but worked the best):
--originalVector3 is the mouse position
vector3new = originalVector3 + (Vector3.FromNormalId(normal) * (blockSize / 2))
*If anyone knows how to make this work with rotations, that will work!
This is the best try I have, but it did not work out well:
local worldCF = target.CFrame:ToWorldSpace(CFrame.new(Vector3.FromNormalId(normal)))
local offset = wCF.Position - target.Position
vector3value = originalVector3 + (offset * (blockSize / 2))
--I tried to find out what is the "normal" compared to the target, and then I tried to find out how was compared to the part in WorldSpace
Thank you for any help!
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.
There are a bunch of ways to have a “snap” to grid feel. By far the easiest is to use Region3:ExpandToGrid() as it does this without us needing to bother about how to calculate. All we need is a region around the mouse.
The method you have tried doing is a good one however you will have to do a bit more maths and logic for it to work.
-- You need a reference CFrame and a "snap" location. In this instance I the snap location can be found simply by rounding the position of the mouse to the closest grid size
local function RoundToNearest(number: number, roundTo: number): number -- Handy function to remember
local x = number + (roundTo / 2)
return x - (x % roundTo)
end
-- To do this convert mouse position to target object space then round to the object space and then reconvert back to world space
local Target = RaycastResult.Position + RaycastResult.Normal -- We do this to avoid edge cases where surface of part is boundary
local BasePart: BasePart = RaycastResult.Instance -- This will be our reference.(I am raycasting from camera to mouse for this)
Target = BasePart.CFrame:PointToObjectSpace(Target)
Target = Vector3.new(
RoundToNearest(Target.X,4),
RoundToNearest(Target.Y,4),
RoundToNearest(Target.Z,4)
)
Target = BasePart.CFrame:ToWorldSpace(CFrame.new(Target))
Preview.CFrame = Target
And Result:
The other method is a LOT simpler simply get a region around the mouse and expand it. (Cant get any simpler than that) Its a lot quicker too however you lose the ability to construct at anything other than the grid. (Sorta like Minecraft where you HAVE to build relative to the grid)
local Target = RaycastResult.Position + RaycastResult.Normal -- Avoid edge case again...
local Region = Region3.new(Target - (GRID_SIZE / 2),Target + (GRID_SIZE/2)):ExpandToGrid(8)
-- We expand the grid to double the size as expand to grid doesn't give the closest grid location GRID_SIZE is (4,4,4)
Preview.CFrame = Region.CFrame
Who knew it only takes 2 lines?!
Hopefully this helps (mind the video quality) I don’t have any hard drive space left lol
This is an example of how it should appear.
(The orange surface would be where my mouse would be pointing, and the green block is the block being placed)
Believe it or not both methods allow for stacking. It is this piece of code that allows that to happen.
local Target = RaycastResult.Position + RaycastResult.Normal
If you look into both pieces of code you can see that the line is present.
This code simply moves the Target away from the surface by 1 stud. This allows for the Snapping to snap to the position of wherever the grid is placed at. I could have moved it 2 studs away for clean-code however that is unnecessary.
One thing to note however, you will always want to check whether the Raycast returns a piece of the vehicle or not. If it does then you can snap to it however if not then don’t