How would i go about making a script where they cannot place blocks outside their island

title.
current script:

local plr = game:GetService("Players").LocalPlayer
local islands = game:GetService("Workspace").Islands.Islands
local island = islands:GetChildren()
local freeIslands = {}
for i, island in pairs(islands:GetChildren()) do
	if island.Occupant.Value == nil then
		table.insert(freeIslands, island)
	end
end

for i,v in pairs(island) do
	v.Touched:Connect(function(otherPart)
		local character = otherPart:FindFirstAncestorOfClass("Model")
		if character then
			-- check if player already claimed an island
			for i, v in pairs(islands:GetChildren()) do
				if v.Occupant.Value == character.Name then
					return -- stop if name is found
				end
			end
			-- the rest of this code will not run if function returns
			local humanoid = character:FindFirstChildOfClass("Humanoid")
			if humanoid then
				local plr = game.Players:GetPlayerFromCharacter(character);
				v.Occupant.Value = plr.Name
			end
		end
	end)
end

workspace screenshot to make things less confusing:

1 Like

Check if this post would help you
https://devforum.roblox.com/t/better-way-of-preventing-players-from-placing-outside-of-plot/1655164/2?u=westside216

If not, I’d go about it using Region3 and FindPartsInRegion3, (now GetPartBoundsInBox)

Perhaps run a FindPartsInRegion3 check on the player’s plot from the ServerSide once they attempt to place a block. If the part they are attempting to place isnt in that area, then dont let it happen.

1 Like

Could you possibly give an example, the forum post didnt really help me understand how it works

The post seems to be from the perspective of the client, where its handling mouse detection.

--// BoundPos is the box they're checking to see if the player is clicking outside of.
--// In your case, the player's entire island should be covered with an invisible part
--// And BoundPos would be that invisible part.
local boundPos = game.Workspace.Plot
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()

local UserInputService = game:GetService("UserInputService")
 

local function isMouseInBoundsOfPlot()
	
	local mousePos = mouse.Hit.p
	print(mousePos.X)
	
	local XMin, XMax = boundPos.Position.X - (boundPos.Size.X / 2), boundPos.Position.X + (boundPos.Size.X / 2)
	local YMin, YMax = boundPos.Position.Y - (boundPos.Size.Y / 2), boundPos.Position.Y + (boundPos.Size.Y / 2)

	return (mousePos.X >= XMin and mousePos.X <= XMax) and (mousePos.Y >= YMin and mousePos.Y <= YMax)
end

local function onInputBegan(input, _gameProcessed)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		print("The left mouse button has been pressed!")
		print(isMouseInBoundsOfPlot())
	end
end

UserInputService.InputBegan:Connect(onInputBegan)


This returns/prints true if they clicked inside of the area. It returns false if they clicked outside.
It is important to note that if you only check this client-sidedly, then exploiters can place blocks outside of their plot. Implement server checks aswell.

1 Like

I got the error: “attempt to index nil with GetMouse”
heres the script:

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

local UserInputService = game:GetService("UserInputService")


local function isMouseInBoundsOfPlot()

	local mousePos = mouse.Hit.p
	print(mousePos.X)

	local XMin, XMax = boundPos.Position.X - (boundPos.Size.X / 2), boundPos.Position.X + (boundPos.Size.X / 2)
	local YMin, YMax = boundPos.Position.Y - (boundPos.Size.Y / 2), boundPos.Position.Y + (boundPos.Size.Y / 2)

	return (mousePos.X >= XMin and mousePos.X <= XMax) and (mousePos.Y >= YMin and mousePos.Y <= YMax)
end

local function onInputBegan(input, _gameProcessed)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		print("The left mouse button has been pressed!")
		print(isMouseInBoundsOfPlot())
	end
end

UserInputService.InputBegan:Connect(onInputBegan)

Is it a ServerScript? If so, then it has to be a localscript.

If it is a localscript, try replacing
local player = game.Players.LocalPlayer
with
local player = game:GetService("Players").LocalPlayer

1 Like

I made that script a local script and i got another error: "Position is not a valid member of Folder Workspace.Islands.Islands

Make sure that Workspace.Islands.Islands is an actual part, not a folder or other class.

1 Like

Well this is what the workspace looks like:

It would instead be
game.Workspace.Islands.Islands[ISLAND1]
or
game.Workspace.Islands.Islands[ISLAND2/3/4/5/6], etc for the respective player. Again, make sure the part covers the entire island where they can place blocks

1 Like

Sorry, I think it might actually be

game.Workspace.Islands.Islands["ISLAND1"]

Forgot parentheses

hello tats actually wrong cause u need to put strings on also game.Workspace is bad practice and you need to use workspace

workspace and game.Workspace are the same.

1 Like

it’s easier to identify with color and it’s good practice to use workspace instead of game.Workspace it’s better cleanliness of your code and better time saving

workspace and game have the same color

Its arguably faster but its irrelevant either way, not necessarily a bad practice. If you wanted to save a half second of your time then go for it.

1 Like

But shouldn’t it be game:getService("workspace"):WaitForChild("Islands").Islands:GetChildren()

Personally, I rather use game:GetService("Workspace")

u seem like the type of guy to use while task.wait() do instead of while true do task.wait()

1: game:GetService(“workspace”) wouldnt work as you forgot to capitalize the W
2: there is no need to getchildren as a table isnt needed here. you’re handling each players clicking personally from likely a starterplayer script

1 Like

You’re right; but shouldn’t I try to get all the islands?

Also, I got another error: “attempt to index nil with X” this is on line 13