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
01 | --<< Variables |
02 |
03 | local Players = game:GetService( 'Players' ) |
04 | local player = Players.LocalPlayer |
05 | local mouse = player:GetMouse() |
06 |
07 | local currentlyBuilding = false |
08 | local addVector = Vector 3. new( 0 , 0.5 , 0 ) |
09 |
10 | --// Main |
11 |
12 | script.Parent.Activated:Connect( function () |
13 | if not currentlyBuilding then |
14 | currentlyBuilding = true |
15 | local viewPart = Instance.new( 'Part' ) |
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
1 | function roundVector 3 (u) |
2 | return Vector 3. new( math.floor(u.x + 0.5 ) |
3 | , math.floor(u.y + 0.5 ) |
4 | , math.floor(u.z + 0.5 ) |
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.
1 | function roundVector 3 (u, nearest) |
2 | nearest = nearest or 1 |
3 | return Vector 3. new( math.floor(u.x / nearest + 0.5 ) * nearest |
4 | , math.floor(u.y / nearest + 0.5 ) * nearest |
5 | , math.floor(u.z / nearest + 0.5 ) * nearest |
6 | ) |
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.
01 | local plr = game:GetService 'Players' .LocalPlayer |
02 | local mouse = plr:GetMouse() |
03 |
04 | local roundnum = function (inp) |
05 | local dec = inp - math.floor(inp) |
06 | if dec < 0.5 then |
07 | return math.floor(inp) |
08 | else |
09 | return math.floor(inp)+ 1 |
10 | end |
11 | end |
12 |
13 | mouse.Button 1 Down:connect( function () |
14 | local pos = mouse.Hit |
15 | local filteredpos = CFrame.new(roundnum(pos.X/ 2 )* 2 , roundnum(pos.Y/ 2 )* 2 + 1 , roundnum(pos.Z/ 2 )* 2 ) |
16 | local p = Instance.new( 'Part' , workspace) |
17 | p.Anchored = true |
18 | p.Size = Vector 3. new( 2 , 2 , 2 ) |
19 | p.CFrame = filteredpos |
20 | end ) |