heres the snap formula
math.round(x/snap+0.5)*snap
i dont remember much change the / and * with each other
heres the snap formula
math.round(x/snap+0.5)*snap
i dont remember much change the / and * with each other
Thanks! This works for snapping it on the ground and preventing it from clipping through. Though, I assume for different orientations I would need to divide the x and z by 2 depending on where I’m dragging it?
This is a bit vague, is “snap” supposed to be the increment at which the part moves, or?
yknow minecraft right? u know how blocks are like snapped to a grid thats just what that line of code does
do that for each x y and z
Yeah I get that, but what is the value of “snap” supposed to be?
the size of the part aka lets say ur parts size x = 2, y = 1 and z = 4
so for each of them u have to put the snap so
local function snap(Number,Snap)
return math.round(Number/Snap+ 0.5) * Snap
end
local snappedvector = Vector3.new(snap(--[[urnum]],part.Size.X),snap(--[[urnum]],part.Size.Y),snap(--[[urnum]],part.Size.Z))
It would work like this
local part = path.to.part
local mouse = game:GetService("Players").LocalPlayer:GetMouse()
game:GetService("UserInputService").InputChanged:Connect(function(input)
if (input.UserInputType == Enum.UserInputType.MouseMovement) then
local ray = workspace:Raycast(part.Position, Vector3.new(0,10,0))
part.Position = Vector3.new(
math.floor(mouse.Position.X),
part.Size.Y*0.5+ray.Position.Y,
math.floor(mouse.Position.Z)
)
end
end)
Oh, I gotcha. Thanks!
So implementing this, it’s actually mostly what I’m looking for, but I want the part to snap to every 1 stud rather than the part’s size.
For example, the part in this video is snapping to every 4 studs since it’s 4x4x4 in size:
Would you have any idea on how to go about this, or would I just need to mess around with it until it works?
What I have currently:
local x = (math.round(mousePos.X / partBeingDragged.Size.X + 0.5) * partBeingDragged.Size.X)
local y = (math.round(mousePos.Y / partBeingDragged.Size.Y + 0.5) * partBeingDragged.Size.Y)
local z = (math.round(mousePos.Z / partBeingDragged.Size.Z + 0.5) * partBeingDragged.Size.Z)
alignPos.Position = Vector3.new(x, y, z)
just round the numbers simply
local x = math.round(mousePos.X)
local y = math.round(mousePos.Y)
local z = math.round(mousePos.Z)
alignPos.Position = Vector3.new(x, y, z)
Yeah I discovered that a bit after experimenting around a bit lol
Currently, this implementation works best for what I’m doing:
mousePos = Vector3.new(math.floor(mousePos.X), mousePos.Y, math.floor(mousePos.Z))
alignPos.Position = mousePos + Vector3.new(0, partBeingDragged.Size.X / 2, 0)
The only issue with it is that it doesn’t allow snapping against walls you drag the part against, only the floors. I’m not 100% sure if there’s a way to detect if you’re dragging a part against a wall with Roblox’s current features
RayCast
allows you to get the Normal
Vector of whatever part was hit by the ray. I actually wrote up a solution earlier that utilized the Normal
Vector to allowing snapping to floors, ceilings, or walls - but I completely forgot to post it.
local UserInputService = game:GetService ("UserInputService")
local Part = Instance.new ("Part")
Part.Size = Vector3.new (math.random (1, 10), math.random (1, 10), math.random (1, 10))
Part.Anchored = true
Part.Parent = workspace
local Player = game:GetService ("Players").LocalPlayer
local Camera = workspace.CurrentCamera
local Params = RaycastParams.new ()
Params.FilterType = Enum.RaycastFilterType.Blacklist
Params.FilterDescendantsInstances = {Player, Part}
UserInputService.InputChanged:Connect (function (input, gameProcessed)
if gameProcessed or input.UserInputType ~= Enum.UserInputType.MouseMovement then
return
end
local mouseLocation = UserInputService:GetMouseLocation ()
local unitRay = Camera:ScreenPointToRay (mouseLocation.X, mouseLocation.Y)
local result = workspace:Raycast (unitRay.Origin, unitRay.Direction * 500, Params)
if result and result.Instance then
local roundedPosition = Vector3.new (math.round (result.Position.X), result.Position.Y, math.round (result.Position.Z))
Part.Position = roundedPosition + result.Normal * (Part.Size / 2)
end
end)
you can use TargetSurface to do that. or see what itslevande here said
Wow, thank you! This is exactly what I need!
I completely forgot that Raycast normals existed, that would’ve helped a loooonnngggg time ago… lol
Yeah, I had no idea Roblox natively supported Normal
Vectors with Raycasting. I only just found out about them recently and they’ve already helped me solve some problems that I could barely wrap my mind around.
Yep. I only found out about them on a previous project I was working on that dealt heavily with Raycasting; very helpful they are.
But nevertheless, thanks for your solution!
By chance is this possible to also change on the snap placement such as instead of 1 per stud it can be from 2 and higher?
( Sorry for the post lol. )
With a slight modification, yes. Define SnapDistance
to be any number you want it to be, then change the roundedPosition
calculation to :
local roundedPosition = Vector3.new (math.round (result.Position.X / SnapDistance) * SnapDistance,
result.Position.Y,
math.round (result.Position.Z / SnapDistance) * SnapDistance)
Awesome thank you this is something I had issues aswell.
I’m getting nil with this method.
I have an object that follows the mouse, which SHOULD be filtered in the params.
However, it sometimes gets nil, it sometimes gets a result.