Currently, I have my system to where you can place parts anywhere but I would like it to where there's a grid and it snaps onto something so you can't just place it freely anywhere. How would you go by doing that? I don't know how to do that.
Here is my script currently and it works fine, I'm not requesting a script. I'm asking on how you would go by making this into a grid placement system.
I'm not sure if this is efficient either so if you could tell me how to make this more efficient that would help :D
--<< Variables local Players = game:GetService('Players') local player = Players.LocalPlayer local mouse = player:GetMouse() local currentlyBuilding = false local addVector = Vector3.new(0, 0.5, 0) --// Main script.Parent.Activated:Connect(function() if not currentlyBuilding then currentlyBuilding = true local viewPart = Instance.new('Part') viewPart.Name = player.Name.."'s ViewPart" viewPart.Parent = workspace viewPart.CanCollide = false viewPart.Transparency = 0.7 viewPart.Anchored = true mouse.TargetFilter = viewPart mouse.Move:Connect(function() while currentlyBuilding do wait() viewPart.Position = mouse.Hit.p + addVector end end) mouse.Button1Down:Connect(function() local position = mouse.Hit.p local createPart = viewPart:Clone() createPart.Parent = workspace createPart.Position = position + addVector createPart.Transparency = 0 createPart.CanCollide = false end) else currentlyBuilding = false local viewPart = workspace:FindFirstChild(player.Name.."'s ViewPart"):Destroy() end end)
The function math.floor
rounds a float down to the integer part.
*math.floor(5.4)
is 5
*math.floor(5.6)
is 5
*math.floor(6.0)
is 6
If we add 0.5 to whatever we're rounding, we get traditional rounding
*math.floor(5.4 + 0.5)
is math.floor(5.9)
= 5
*math.floor(5.6 + 0.5)
is math.floor(6.1)
= 6
*math.floor(6.0)
is 6 is math.floor(6.5)
= 6
To round a vector3, we can round each coordinate individually
function roundVector3(u) return Vector3.new( math.floor(u.x + 0.5) , math.floor(u.y + 0.5) , math.floor(u.z + 0.5) )
So basically whenever you set a brick's position in the code above, first run it through roundVector3
for a grid-based system.
The above code works only for a grid of increment 1. What if we want a grid of size 4?
To round to the nearest arbitrary integer, if we divide what we're rounding, round, then multiply, we get a correctly rounded-to-the-nearest-thingy answer.
function roundVector3(u, nearest) nearest = nearest or 1 return Vector3.new( math.floor(u.x / nearest + 0.5) * nearest , math.floor(u.y / nearest + 0.5) * nearest , math.floor(u.z / nearest + 0.5) * nearest )
In line 12, assuming the Activated event belongs to a Tool (TextButton’s have this event), The Activated event of a Tool has the same behaviour as the Button1Down event. You should maybe remove the button1down event and just have your code in that event belong to the activated one.
Sorry if my code is spaggeti code. I would recommend using some maths to round the numbers to the nearest 2 or any other number by using math.floor(). This script is just an example.
local plr = game:GetService'Players'.LocalPlayer local mouse = plr:GetMouse() local roundnum = function(inp) local dec = inp - math.floor(inp) if dec < 0.5 then return math.floor(inp) else return math.floor(inp)+1 end end mouse.Button1Down:connect(function() local pos = mouse.Hit local filteredpos = CFrame.new(roundnum(pos.X/2)*2, roundnum(pos.Y/2)*2+1, roundnum(pos.Z/2)*2) local p = Instance.new('Part', workspace) p.Anchored = true p.Size = Vector3.new(2,2,2) p.CFrame = filteredpos end)