Math.Round() is not rounding away from zero?

I’m using the Math.Round() Function to snap the player’s mouse position to a grid, but when the cursor is placed directly between two points it switches between them rather than rounding to the position that is the furthest from 0.

Video:

My Code:

-- Initialise
function Walls.Init()
	
	PreviewObj = Wall:Clone()
	PreviewObj.Parent = game.Workspace["Facility-".. plr.UserId]
	Tooltip.Update(0, "Click & Move To Preview")
	
	
	Connection = RS.Heartbeat:Connect(function()
		local newPosition = Gridspace.Convert(mouse.Hit.Position, 5, Y_Plane)
		if PreviewObj.StartPoint.Position ~= newPosition then
			
			-- Validate New Position
			if Gridspace.Validate(newPosition, 5, Y_Plane) then
				TS:Create(PreviewObj.StartPoint,TweenInfo.new(0.1,Enum.EasingStyle.Linear), {Position = newPosition}):Play()
			end
		end
		
	end)
	
end
-- Convert to Grid
function Gridspace.Convert(position, gridSize, Y_Plane)
	local plr = game.Players.LocalPlayer
	
	local OriginPart = game.Workspace["Facility-".. plr.UserId].PrimaryPart
	local UnsnappedRelative = OriginPart.CFrame:PointToObjectSpace(position)
	
	local SnappedRelative = Vector3.new(
		math.round(UnsnappedRelative.X / gridSize) * gridSize,
		Y_Plane,
		math.round(UnsnappedRelative.Z / gridSize) * gridSize
	)
	local SnappedWorld = OriginPart.CFrame:PointToWorldSpace(SnappedRelative)

	return SnappedWorld
end

Your mouse must be hitting the part and causing a loop, so you should turn off the CanQuery property for it.

I’m not sure what you mean by hitting the part?

Edit: Regardless, I set all of the parts’ CanQuery properties to false & it does not affect anything

When the position switching happens, mouse.Hit switches between hitting the part (and its location is at one side of a grid line) and hitting the ground (at the other side of the grid line, making the part enter a movement loop).
image
I guess CanQuery isn’t working here, but it looks like Mouse has a TargetFilter property, so maybe it’ll stop this from happening if you try that

This doesn’t seem to be the cause. I switched from using the RunService to mouse.Move & it solves the issue. If that were the case, doing this should still have yielded the same result, right? I’m not sure why the RunService isn’t cooperating & I’m not thrilled about this alternate method because it’ll require extra lines of code since it doesn’t account for movement outside of the player’s mouse (i.e. moving the camera around won’t update the preview anymore) but it’s the only route I can currently see

-- Initialise
function Walls.Init()
	
	PreviewObj = Wall:Clone()
	PreviewObj.Parent = game.Workspace["Facility-".. plr.UserId]
	Tooltip.Update(0, "Click & Move To Preview")
	
	
	Connection = mouse.Move:Connect(function()
		local newPosition = Gridspace.Convert(mouse.Hit.Position, 5, Y_Plane)
		if PreviewObj.StartPoint.Position ~= newPosition then
			
			-- Validate New Position
			if Gridspace.Validate(newPosition, 5, Y_Plane) then
				TS:Create(PreviewObj.StartPoint,TweenInfo.new(0.1,Enum.EasingStyle.Linear), {Position = newPosition}):Play()
			end
		end
		
	end)
	
end

If you want to round up, away from 0, you should be using math.ceil rather than math.round

1 Like

I guess my logic didn’t hold up, I’m not sure why mouse.Move gives me the correct result as well without using a TargetFilter, but that’s all I needed, thank you :sparkles:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.