i kinda bad in math so idk how to caculate the grid thing for dat
RunService.RenderStepped:Connect(function()
if FuniturePlaceholder ~= nil then
local FunitureInfo = require(ClientModule:WaitForChild("FunitureInfo")[FuniturePlaceholder.Name])
local GetMouseRaycast = MainClient.MouseRaycast(FuniturePlaceholder)
local RaycastInstance = GetMouseRaycast.Instance
if GetMouseRaycast and RaycastInstance and RaycastInstance.Parent.Name == FunitureInfo.Place then
local MousePos = GetMouseRaycast.Position
local FuniturePos = Vector3.new(0, FuniturePlaceholder.PrimaryPart.Size.Y / 2, 0)
FuniturePos += MousePos
local X = math.round(FuniturePos.X / GridSize) * GridSize
local Y = math.round(FuniturePos.Y)
local Z = math.round(FuniturePos.Z / GridSize) * GridSize
FuniturePos = CFrame.new(X, Y, Z)
TweenService:Create(FuniturePlaceholder.PrimaryPart, TweenInfo.new(0.5, Enum.EasingStyle.Elastic), {CFrame = FuniturePos * CFrame.Angles(0, math.rad(Rotation), 0)}):Play()
end
end
end)
I was recently developing a similar system and encountered the same issue, which is due to a particular behavior when rounding positions. This behavior arises because the rounding process doesn’t consider the boundaries correctly, leading to discrepancies.
I used this code where I set a posAnt variable to store the “axis” position, so to speak, of the object where we want to place it. This posAnt serves as a reference point to help us manage the rounding of the position.
My rounding function works as follows:
local function snap(x: number, posAnt: number, offset: number) : number
if not offset then
offset = 0
end
local rounded : number = bloqueDimension * math.floor(x / bloqueDimension + offset)
if x <= posAnt - bloqueDimension/2 then
rounded = bloqueDimension * math.floor((x-0.01) / bloqueDimension + offset)
end
return rounded + bloqueDimension/2
end
And this is how I use it
local rayo = Ray.new(mouse.UnitRay.Origin, (mouse.UnitRay.Direction * 1000)) -- Crear un rayo desde el mouse
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = objetosAIgnorar
local raycastResult = game.Workspace:Raycast(rayo.Origin, rayo.Direction * 1000, raycastParams)
if raycastResult then
local hit = raycastResult.Instance
local punto = raycastResult.Position
if not posAnterior then
posAnterior = clonVistaPrevia.Position
end
clonPruebas.Position = punto
clonVistaPrevia.Position = Vector3.new(
snap(punto.X, posAnterior.X),
snap(punto.Y, posAnterior.Y, 0.01),
snap(punto.Z, posAnterior.Z)
)
if posAnterior ~= clonVistaPrevia.Position then
posAnterior = clonVistaPrevia.Position
if hit.Name == "Default" then
posAnterior = hit.Position
end
end
clonPosAnterior.Position = posAnterior
end
I’m attaching a video for you to better understand (the red cube represents the posAnt position).