Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How do I make a grid placement system work?

Asked by 6 years ago

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)
0
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. User#19524 175 — 6y

3 answers

Log in to vote
0
Answered by
fredfishy 833 Moderation Voter
6 years ago

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.

Arbitrary rounding

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
                      )
0
Thank you it works, but when I place down a few parts it isn't flush with the previous parts it snaps to a grid but it doesn't place properly on that grid. I understand what you mean by the rounding and the math.floor but the Arbitrary rounding function is confusing. YabaDabaD0O 505 — 6y
0
....did lua seriously rename modulus to floor? ;-; User#19492 0 — 6y
Ad
Log in to vote
0
Answered by 6 years ago

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.

0
Nope, it's a GUI, once you click the button it initiates the rest of the code. The Button1Down is linked to the mouse so when they click on the screen it creates the part, if I removed the event then it wouldn't work as a placement system. YabaDabaD0O 505 — 6y
Log in to vote
0
Answered by 6 years ago

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)

Answer this question