How should I go about doing this?

I’m trying to make a cage that can be spawned by the players in the game, the cage will then update its position so that after it traps a player, it blacklists the player who was trapped so that it can go target another player.

I’ve tried making something like this already, but a lot of times it would either overload the script for become extremely laggy…

So how do you think I should go about doing this?

I dont understand exactly what you mean by this.

1 Like

i think she wants us to make a script where when player touched the cage the player gets teleported inside it. and then the player get blacklisted so when he touched the cage again it does not register or teleports him back again. also, the cage should randomly teleport .

Ok so basically:

  1. A Cage is spawned into the map (I’ve already got this over with)

  2. The cage uses Region3’s to find players in its radius

  3. After that, it uses table.sort to sort the closes position so that it can chase after the player closest to it.

  4. After it catches the player, that player is blacklisted, and then it goes on to chase other players.

I’ve already got a script down (kind of) but It keeps getting this error.

-- Declare variables for the player and the object that will follow them
local PrimaryPart = script.Parent
local following = false

local followZone = Region3.new(PrimaryPart.Position - Vector3.new(125, 1, 125), PrimaryPart.Position + Vector3.new(125, 100, 125))
local partsInFollowZone = {} -- Parts in the region3

local currentlyCaptured = {} -- the table that blacklists players who've already been captured

-- Create a function that will move the PrimaryPart to a position behind the player's character every frame
function followPlayer(player)
	local playerPosition = player.Character.HumanoidRootPart.Position
	
	repeat
		if playerPosition.X > PrimaryPart.Position.X then
			PrimaryPart.Position += Vector3.new(1, 0, 0)
		elseif playerPosition.X < PrimaryPart.Position.X then
			PrimaryPart.Position -= Vector3.new(1, 0, 0)
		end
		
		if playerPosition.Y > PrimaryPart.Position.Y then
			PrimaryPart.Position += Vector3.new(1, 0, 0)
		elseif playerPosition.Y < PrimaryPart.Position.Y then
			PrimaryPart.Position -= Vector3.new(1, 0, 0)
		end
		
		if playerPosition.Z > PrimaryPart.Position.Z then
			PrimaryPart.Position += Vector3.new(1, 0, 0)
		elseif playerPosition.Z < PrimaryPart.Position.Z then
			PrimaryPart.Position -= Vector3.new(1, 0, 0)
		end
		
		task.wait(.5)
	until PrimaryPart.Position == playerPosition
end

-- Run the followPlayer function every frame
game:GetService("RunService").Heartbeat:Connect(function()
	if following == false then
		for i, v in pairs(workspace:GetPartBoundsInBox(followZone.CFrame, followZone.Size)) do
			if v.Parent == game.Players:GetPlayerFromCharacter(v.Parent) then
				table.insert(partsInFollowZone, v)

				table.sort(partsInFollowZone, function(a, b)
					return a > b
				end)
			end
		end
		
		following = true
		followPlayer(partsInFollowZone[1].Parent)
	end
end)
 Workspace.Part.Script:51: attempt to index nil with 'Parent'

GetPartBoundsInBox is a very slow way to check for the nearest player. You should check each character from the children of the Players service instead.

1 Like

Ok so I’ve updated my code like this, the part now moves and goes to the player but the issue is even though the player was added into the table of people who were captured, the part still keeps following the player…

-- Declare variables for the player and the object that will follow them
local PrimaryPart = script.Parent
local following = false

local followZone = Region3.new(PrimaryPart.Position - Vector3.new(125, 1, 125), PrimaryPart.Position + Vector3.new(125, 100, 125))
local partsInFollowZone = {} -- Parts in the region3

local currentlyCaptured = {} -- the table that blacklists players who've already been captured

-- Create a function that will move the PrimaryPart to a position behind the player's character every frame

function touched(hit)
	local player = hit.Parent
	
	table.insert(currentlyCaptured, player)
end

function followPlayer(player)
	local playerPosition = player.PrimaryPart.Position

	repeat
		print(currentlyCaptured)
		playerPosition = player.PrimaryPart.Position
		
		if playerPosition.X > PrimaryPart.Position.X then
			PrimaryPart.Position += Vector3.new(1, 0, 0)
		elseif playerPosition.X < PrimaryPart.Position.X then
			PrimaryPart.Position -= Vector3.new(1, 0, 0)
		end

		if playerPosition.Y > PrimaryPart.Position.Y then
			PrimaryPart.Position += Vector3.new(0, 1, 0)
		elseif playerPosition.Y < PrimaryPart.Position.Y then
			PrimaryPart.Position -= Vector3.new(0, 1, 0)
		end

		if playerPosition.Z > PrimaryPart.Position.Z then
			PrimaryPart.Position += Vector3.new(0, 0, 1)
		elseif playerPosition.Z < PrimaryPart.Position.Z then
			PrimaryPart.Position -= Vector3.new(0, 0, 1)
		end

		task.wait(.025)
	until currentlyCaptured[player]
	
	following = false
end

-- Run the followPlayer function every frame
game:GetService("RunService").Heartbeat:Connect(function()
	task.wait(2)
	
	if following == false then
		for i, v in pairs(game.Players:GetPlayers()) do
			if not currentlyCaptured[v] then
				table.insert(partsInFollowZone, v.Character)

				table.sort(partsInFollowZone, function(a, b)
					return a.PrimaryPart.Position > b.PrimaryPart.Position
				end)
			end
		end
		
		print(partsInFollowZone)
		print(partsInFollowZone[1])

		following = true
		followPlayer(partsInFollowZone[1])
	end
end)

PrimaryPart.Touched:Connect(function(hit)
	if game.Players:GetPlayerFromCharacter(hit.Parent) then
		touched(hit)
	end
end)
table.insert(currentlyCaptured, player)  --Puts character in list

...

for i, v in pairs(game.Players:GetPlayers()) do
			if not currentlyCaptured[v] then --Checks for player in dictionary
				table.insert(partsInFollowZone, v.Character)

You are putting the character in the table with a numbered index, such as [1] = Character. But you’re checking as if you’ve put it in like a dictionary. Change the line with table.insert to this:

currentlyCaptured[player] = true --Can be any value except nil, since we only check for this key, not its value.
1 Like
-- Declare variables for the player and the object that will follow them
local PrimaryPart = script.Parent
local following = false

local followZone = Region3.new(PrimaryPart.Position - Vector3.new(125, 1, 125), PrimaryPart.Position + Vector3.new(125, 100, 125))
local partsInFollowZone = {} -- Parts in the region3

local currentlyCaptured = {} -- the table that blacklists players who've already been captured

-- Create a function that will move the PrimaryPart to a position behind the player's character every frame

function touched(hit)
	local player = hit.Parent

	if not currentlyCaptured[player] then
		currentlyCaptured[player] = true
	end
end

function followPlayer(player)
	local playerPosition = player.PrimaryPart.Position

	repeat
		print(currentlyCaptured)
		playerPosition = player.PrimaryPart.Position

		if playerPosition.X > PrimaryPart.Position.X then
			PrimaryPart.Position += Vector3.new(1, 0, 0)
		elseif playerPosition.X < PrimaryPart.Position.X then
			PrimaryPart.Position -= Vector3.new(1, 0, 0)
		end

		if playerPosition.Y > PrimaryPart.Position.Y then
			PrimaryPart.Position += Vector3.new(0, 1, 0)
		elseif playerPosition.Y < PrimaryPart.Position.Y then
			PrimaryPart.Position -= Vector3.new(0, 1, 0)
		end

		if playerPosition.Z > PrimaryPart.Position.Z then
			PrimaryPart.Position += Vector3.new(0, 0, 1)
		elseif playerPosition.Z < PrimaryPart.Position.Z then
			PrimaryPart.Position -= Vector3.new(0, 0, 1)
		end

		task.wait(.025)
	until currentlyCaptured[player] == true

	following = false
end

-- Run the followPlayer function every frame
game:GetService("RunService").Heartbeat:Connect(function()
	task.wait(2)

	if following == false then
		for i, v in pairs(game.Players:GetPlayers()) do
			if not currentlyCaptured[v] then
				table.insert(partsInFollowZone, v.Character)

				table.sort(partsInFollowZone, function(a, b)
					return a.PrimaryPart.Position > b.PrimaryPart.Position
				end)
			end
		end

		print(partsInFollowZone)
		print(partsInFollowZone[1])

		following = true
		followPlayer(partsInFollowZone[1])
	end
end)

PrimaryPart.Touched:Connect(function(hit)
	if game.Players:GetPlayerFromCharacter(hit.Parent) then
		touched(hit)
	end
end)

It seems like it’s stopped, although this error keeps exploding the output and I have no idea why.

  14:45:59.228  Workspace.Part.Script:61: attempt to compare Vector3 < Vector3  -  Server - Script:61
  14:45:59.228  Stack Begin  -  Studio
  14:45:59.228  Script 'Workspace.Part.Script', Line 61  -  Studio - Script:61
  14:45:59.228  Script 'Workspace.Part.Script', Line 60  -  Studio - Script:60
  14:45:59.228  Stack End  -  Studio

And this also keeps happening to the captured players where my player is added multiple times causing lag

image