Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do I make a grid placement system work?

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)

1 comment

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.

3 answers

✓ Accepted answer

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
                      )

2 comments

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.

0

....did lua seriously rename modulus to floor? ;-;

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.

1 comment

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.

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)

This discussion is preserved as it was. New answers, comments, and votes are closed.