Put an invisible, CanCollide false, Size = .1,.1,.1 brick where the mouse is every time you move it. The little extra offset usually lets the rounding functions work out right.
The problem is that when your mouse hits the face coming from a negative direction the code it will be rounded into the next “Section” of the grid. There is no easy way math wise to determine what direction the player is “meaning” so my hack little fix is literally to force in a little offset.
local Part = Instance.new("Part",game.Workspace);
Part.Size = Vector3.new(.1.1.1);
Part.Transpareny = 1;
Part.CanCollide = false;
while wait() do
Part.CFrame = Mouse.Hit;
end
local Player = game.Players.LocalPlayer
local Build_Storage = game:GetService("ReplicatedStorage"):WaitForChild("Buildables")
local Concrete_Block = Build_Storage:WaitForChild("Concrete")
local Placed_Blocks = game.Workspace:WaitForChild("Placed_Blocks")
local Ignore_Blocks = game.Workspace:WaitForChild("Ignore_Blocks")
local Base = game.Workspace:WaitForChild("Base")
local Mouse = Player:GetMouse()
Mouse.TargetFilter = Ignore_Blocks
local target = nil
local pos = nil
local norm = nil
local MAX_PLACEMENT_DISTANCE = 2000
function doFakeMouseStuff()
local ignoreList = {Ignore_Blocks} --game.Workspace:WaitForChild("BaseStore"):GetChildren()
local mouseRay = Mouse.UnitRay
local newRay = Ray.new(mouseRay.Origin, mouseRay.Direction.unit * MAX_PLACEMENT_DISTANCE)
target, pos, norm = workspace:FindPartOnRayWithIgnoreList(newRay, ignoreList)
end
game:GetService("RunService").RenderStepped:connect(function()
doFakeMouseStuff()
end)
function round(vec, block)
local posx = math.floor(vec.X / block.PrimaryPart.Size.X + 0.5) * block.PrimaryPart.Size.X
local posy = math.floor(vec.Y / block.PrimaryPart.Size.Y + 0.5) * block.PrimaryPart.Size.Y
local posz = math.floor(vec.Z / block.PrimaryPart.Size.Z + 0.5) * block.PrimaryPart.Size.Z
return Vector3.new(posx, posy, posz)
end
local item = Concrete_Block:Clone()
item.Parent = Ignore_Blocks
Mouse.Move:connect(function()
if item and pos and norm then
doFakeMouseStuff() -- Just to be cetain that the data is up to date.
local endPos = round(pos + (norm * (item.PrimaryPart.Size*.5)), item)
item:SetPrimaryPartCFrame(CFrame.new(endPos))
end
end)
Mouse.Button1Down:connect(function()
local part = item:Clone()
part:SetPrimaryPartCFrame(CFrame.new(item.PrimaryPart.Position))
part.Name = 'block'
part.Parent = workspace
end)