Help with ai stopping (PLEASE READ)

Hi i have this code here which and ai chases you and when you enter the safe zone it should stop chasing you and find another player to chase but the thing is the ai comes very close to the safe zone part which i don’t want but idk how to do this i have tried a few things but they have not worked

here is the code:

local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")

local SAFE_ZONE_TAG = "InSafeZone"
local ENEMY = workspace["."]
local safeZone = workspace.Safezone
local DETECTION_RADIUS = 50
local maxDistance = 45


local function isPlayerVisible(enemy, target)
	local direction = (target.Position - enemy.HumanoidRootPart.Position).Unit
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {enemy}
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude

	local raycastResult = workspace:Raycast(enemy.HumanoidRootPart.Position, direction * DETECTION_RADIUS, raycastParams)

	if raycastResult then
		local hitPart = raycastResult.Instance
		if hitPart and hitPart:IsDescendantOf(target.Parent) then
			return true
		end
	end

	return false
end

local function moveToTarget(enemy, target)
	local path = PathfindingService:CreatePath()

	path:ComputeAsync(enemy.HumanoidRootPart.Position, target.Position)
	if path.Status == Enum.PathStatus.Success then
		local waypoints = path:GetWaypoints()
		for _, waypoint in ipairs(waypoints) do
			enemy.Humanoid:MoveTo(waypoint.Position)
			local reached = enemy.Humanoid.MoveToFinished
			if not reached then
				print("Failed to reach waypoint")
				break
			end
		end
	else
		print("Path computation failed:", path.Status)
	end
end

local function detectAndChase(enemy)
	while task.wait() do
		local partsInRadius = workspace:GetPartBoundsInRadius(enemy.HumanoidRootPart.Position, DETECTION_RADIUS)

		for _, part in ipairs(partsInRadius) do
			local player = Players:GetPlayerFromCharacter(part.Parent)
			if player and player.Character and not player.Character:GetAttribute(SAFE_ZONE_TAG) then
				if isPlayerVisible(enemy, part) then
					print("Chasing player:", player.Name)
					moveToTarget(enemy, part)
				end
			end
		end
	end
end

safeZone.Touched:Connect(function(hit)
	local player = Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		player.Character:SetAttribute(SAFE_ZONE_TAG, true)
		print(player.Name, "entered safe zone")
	end
end)

safeZone.TouchEnded:Connect(function(hit)
	local player = Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		player.Character:SetAttribute(SAFE_ZONE_TAG, false)
		print(player.Name, "left safe zone")
	end
end)

-- Start Detection
task.spawn(function()
	detectAndChase(ENEMY)
end)

Also here is a video of my ai:

robloxapp-20250112-1842565.wmv

And this is how i want my ai to work like:

robloxapp-20250112-1845212.wmv

I hope you guys can help me I really want to finish this

7 Likes

TouchEnded is very unreliable, and it can easily trigger by just jumping. You can try other methods of detection such as Raycasting and Region3

4 Likes

i want to know how to stop the ai from coming any closer once I enter the safe zone I will do that change later

4 Likes

That’s the reason why, it thinks you have left the safezone and it keeps chasing you thinking you’re still in the map

5 Likes

so what should i change it to region3 or raycast

3 Likes

Either works, or a combination of both to save server resources would be best.

2 Likes

ok i will do that so you think that will fix it?

1 Like

Nothing else in this script would make it so it keeps chasing you, unless outside interference from a different script is changing the attribute to false

Give this a go: ZonePlus v3.2.0 | Construct dynamic zones and effectively determine players and parts within their boundaries

1 Like

hi for some reason i did this and it still goes inside of the safe zone:


local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")

local SAFE_ZONE_TAG = "InSafeZone"
local ENEMY = workspace["."]
local safeZone = workspace.Safezone
local DETECTION_RADIUS = 50
local maxDistance = 45

local function isPlayerVisible(enemy, target)
	local direction = (target.Position - enemy.HumanoidRootPart.Position).Unit
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {enemy}
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude

	local raycastResult = workspace:Raycast(enemy.HumanoidRootPart.Position, direction * DETECTION_RADIUS, raycastParams)

	if raycastResult then
		local hitPart = raycastResult.Instance
		if hitPart and hitPart:IsDescendantOf(target.Parent) then
			return true
		end
	end

	return false
end

local function moveToTarget(enemy, target)
	local path = PathfindingService:CreatePath()

	path:ComputeAsync(enemy.HumanoidRootPart.Position, target.Position)
	if path.Status == Enum.PathStatus.Success then
		local waypoints = path:GetWaypoints()
		for _, waypoint in ipairs(waypoints) do
			enemy.Humanoid:MoveTo(waypoint.Position)
			local reached = enemy.Humanoid.MoveToFinished
			if not reached then
				print("Failed to reach waypoint")
				break
			end
		end
	else
		print("Path computation failed:", path.Status)
	end
end

local function detectAndChase(enemy)
	while task.wait() do
		local partsInRadius = workspace:GetPartBoundsInRadius(enemy.HumanoidRootPart.Position, DETECTION_RADIUS)

		for _, part in ipairs(partsInRadius) do
			local player = Players:GetPlayerFromCharacter(part.Parent)
			if player and player.Character and not player.Character:GetAttribute(SAFE_ZONE_TAG) then
				if isPlayerVisible(enemy, part) then
					print("Chasing player:", player.Name)
					moveToTarget(enemy, part)
				end
			end
		end
	end
end

local function checkSafeZonePlayers()
	local region = Region3.new(
		safeZone.Position - (safeZone.Size / 2),
		safeZone.Position + (safeZone.Size / 2)
	)

	local overlappingParts = workspace:FindPartsInRegion3(region, nil, math.huge)
	local playersInSafeZone = {}

	for _, part in ipairs(overlappingParts) do
		local player = Players:GetPlayerFromCharacter(part.Parent)
		if player then
			player.Character:SetAttribute(SAFE_ZONE_TAG, true)
			playersInSafeZone[player.Name] = true
		end
	end

	for _, player in ipairs(Players:GetPlayers()) do
		if not playersInSafeZone[player.Name] and player.Character then
			player.Character:SetAttribute(SAFE_ZONE_TAG, false)
		end
	end
end


task.spawn(function()
	while task.wait(1) do
		checkSafeZonePlayers()
	end
end)

-- Start Detection
task.spawn(function()
	detectAndChase(ENEMY)
end)
1 Like

Print

player.Character:GetAttribute(SAFE_ZONE_TAG) 

before chasing the player, and also make a break condition on the pathfinding so that it stops if the player’s atrribute changes

it says false??(30charrrrrrrrrrrrrrrrrrrrrr)

for _, part in ipairs(overlappingParts) do
		local player = Players:GetPlayerFromCharacter(part.Parent)
		if player then
			player.Character:SetAttribute(SAFE_ZONE_TAG, true)
			playersInSafeZone[player.Name] = true
			break
		end
	end

	for _, player in ipairs(Players:GetPlayers()) do
		if not playersInSafeZone[player.Name] and player.Character then
			player.Character:SetAttribute(SAFE_ZONE_TAG, false)
			break
		end

It checks it every one second, does it say true after a second or so?

no (30 30charrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrracter)

i don’t understand why it does this

Have you tried checking if its even detecting the player in the safezone? Print a message to see if it sets it to true at all

Once it enters the safe zone? (300000000000000000000)

Yes__________________ (wordfill)

once i enter the safe zone it said false then true