Add border to placement system

I know this sounds confusing, but I want to limit the player’s builds and make them only build in a specific area, but I don’t know how to properly execute this process. Like this: There is a box. The player can build inside the box but cannot build outside the box.

Code: yes, my code is messy.

-- Local Script
local UIS = game:GetService("UserInputService")
local replicatedStorage = game:GetService("ReplicatedStorage")

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local tool = script.Parent
local UI = tool:FindFirstChild("ToolUI")

local enabled = false
local chosenPartValue = player.playerstats.Selected

local connection1 = nil

local chosenClone

local REACH = 100

local function pos(vector,grid) 
	return Vector3.new(math.floor(vector.X/grid+.5)*grid, math.floor(vector.Y/grid+.5)*grid, math.floor(vector.Z/grid+.5)*grid) 
end

function input(keycode, gps)
	if keycode.KeyCode == Enum.KeyCode.R then
		if enabled == true then
			chosenClone:SetPrimaryPartCFrame(chosenClone:GetPrimaryPartCFrame() * CFrame.Angles(0,math.pi/2,0))
		end
	end
end

function equipped()
	enabled = true
	if not player.PlayerGui:FindFirstChild(UI.Name) then
		local clone = UI:Clone()
		clone.Parent = player.PlayerGui
		clone.MainFrame.Visible = true
	else
		player.PlayerGui[UI.Name].MainFrame.Visible = true
	end
	
	chosenClone = chosenPartValue.Value:Clone()
	chosenClone.Parent = workspace.LocalItems
	
	for i, v in pairs(chosenClone:GetChildren()) do
		if v:IsA("Part") or v:IsA("UnionOperation") then
			v.CanCollide = false
			v.Color = Color3.fromRGB(0,200,0)
			if v.Name ~= "Hitbox" then
				v.Transparency = 0.5
			else
				v.Transparency = 1
			end
		end
	end
	
	local function move()
		local unitRay = mouse.UnitRay

		local castParams = RaycastParams.new()
		castParams.FilterDescendantsInstances = { player.Character, chosenClone }
			
		local result = workspace:Raycast(
			unitRay.Origin, unitRay.Direction * REACH,
			castParams
		)
			

		if result then
			chosenClone:MoveTo(pos(result.Position + result.Normal * 1.5, 0.1))
		end
	end
	
	connection1 = mouse.Move:Connect(move)
end

function unequipped()
	enabled = false
	player.PlayerGui[UI.Name].MainFrame.Visible = false
	chosenClone:Destroy()
	connection1:Disconnect()
end

function activated()
	if enabled == true then
		replicatedStorage:WaitForChild("AddBlock"):FireServer(chosenPartValue, chosenClone:GetPrimaryPartCFrame())
	end
end

UIS.InputBegan:Connect(input)

tool.Activated:Connect(activated)

tool.Unequipped:Connect(unequipped)
tool.Equipped:Connect(equipped)

-- Server Script
local replicatedStorage = game:GetService("ReplicatedStorage")

function placeFurniture(player, typeoffurniture, cframe)
	local furniture = typeoffurniture.Value:Clone()
	furniture.Parent = workspace.WorkspaceBlocks
	furniture:SetPrimaryPartCFrame(cframe)
end

replicatedStorage:WaitForChild("AddBlock").OnServerEvent:Connect(placeFurniture)

Can someone find a solution?

2 Likes

i think you can use regions

i personally didn’t deal with regions that much so i can’t help you that much with that but give it a try!

1 Like

You can Use Region 3 To Check if the Player is in A Region Or Not.
You Can Basically Set Up A Value And
Change its Value To true If the Player is in the Region

Next You can Simply Check Before Placing the Objects that If the Value is true Or Not.

Here is A Tutorial That Can Help.
The Above One is About Sound Regions but
Instead of Playing a Sound You can Just Change the Value to True.

1 Like

I know Region3, but is it possible if I can make it so when it’s fully inside the region that is is allowed to place objects. I appreciate everyone’s responses and whatnot!

I believe you could also use 3D collision maths, an example of this

local CurrentPos = ExampleRoot.Position
local Min = ExampleRegion.Position - ExampleRegion.Size/2
local Max = ExampleRegion.Position + ExampleRegion.Size/2

local InRegion = false

if CurrentPos.X > Min.X and CurrentPos.Y > Min.Y and CurrentPos.Z > Min.Z and CurrentPos.X < Max.X and CurrentPos.Y < Max.Y and CurrentPos.Z < Max.Z then
   InRegion = true
end

print("InRegion: "..tostring(InRegion))

This math will bascially detect if a players root position is within the pos and size of a region.

thanks for everyone that replied!

I still don’t understand how this works…

You’ll get there someday if you put your heart in it.