Enemy not behaving as intended

I’m trying to use reigion3 to detect when I’m within range for the enemy to chase and attack me, I cant figure out why its not working.

local enemiesFolder = game.Workspace:WaitForChild("Enemies")
local players = game:GetService("Players")
local attackRange = 5 -- Distance within which the enemy will attack the player
local chaseRange = 20 -- Distance within which the enemy will start chasing the player
local attackCooldown = 2 -- Time in seconds between attacks

-- Function to handle damage dealing
local function dealDamage(player, damage)
	local character = player.Character
	if character then
		local humanoid = character:FindFirstChildOfClass("Humanoid")
		if humanoid then
			humanoid:TakeDamage(damage)
			print("Dealing " .. damage .. " damage to player: " .. player.Name)
		else
			print("Humanoid not found in player: " .. player.Name)
		end
	else
		print("Character not found for player: " .. player.Name)
	end
end

-- Function to get players within a given region
local function getPlayersInRange(position, range)
	local region = Region3.new(position - Vector3.new(range, range, range), position + Vector3.new(range, range, range))
	local parts = workspace:FindPartsInRegion3WithWhiteList(region, players:GetPlayers(), math.huge)
	local playersInRange = {}

	for _, part in ipairs(parts) do
		local character = part.Parent
		local player = players:GetPlayerFromCharacter(character)
		if player then
			table.insert(playersInRange, player)
		end
	end

	return playersInRange
end

-- Function to handle enemy behavior
local function handleEnemy(enemy)
	local humanoid = enemy:FindFirstChildOfClass("Humanoid")
	local rootPart = enemy:FindFirstChild("HumanoidRootPart")
	local animationsFolder = enemy:FindFirstChild("Animations")
	local statsFolder = enemy:FindFirstChild("Stats")

	if not humanoid then
		warn("Missing Humanoid in enemy model:", enemy.Name)
		return
	end
	if not rootPart then
		warn("Missing HumanoidRootPart in enemy model:", enemy.Name)
		return
	end
	if not animationsFolder then
		warn("Missing Animations folder in enemy model:", enemy.Name)
		return
	end
	if not statsFolder then
		warn("Missing Stats folder in enemy model:", enemy.Name)
		return
	end

	local walkAnimation = animationsFolder:FindFirstChild("WalkAnimation")
	local attackAnimation1 = animationsFolder:FindFirstChild("AttackAnimation1")
	local attackAnimation2 = animationsFolder:FindFirstChild("AttackAnimation2")

	if not walkAnimation then
		warn("Missing WalkAnimation in Animations folder:", enemy.Name)
		return
	end
	if not attackAnimation1 then
		warn("Missing AttackAnimation1 in Animations folder:", enemy.Name)
		return
	end
	if not attackAnimation2 then
		warn("Missing AttackAnimation2 in Animations folder:", enemy.Name)
		return
	end

	local health = statsFolder:FindFirstChild("Health")
	local damage = statsFolder:FindFirstChild("Damage")

	if not health then
		warn("Missing Health in Stats folder:", enemy.Name)
		return
	end
	if not damage then
		warn("Missing Damage in Stats folder:", enemy.Name)
		return
	end

	print("Enemy " .. enemy.Name .. " is set up correctly")

	local walkAnimTrack = humanoid:LoadAnimation(walkAnimation)
	local attackAnimTrack1 = humanoid:LoadAnimation(attackAnimation1)
	local attackAnimTrack2 = humanoid:LoadAnimation(attackAnimation2)
	local attacking = false

	-- Function to play a random attack animation
	local function playAttackAnimation()
		if math.random(1, 2) == 1 then
			attackAnimTrack1:Play()
			print("Playing AttackAnimation1 for enemy: " .. enemy.Name)
		else
			attackAnimTrack2:Play()
			print("Playing AttackAnimation2 for enemy: " .. enemy.Name)
		end
	end

	-- Function to handle the attack
	local function attackPlayer(player)
		if attacking then return end
		attacking = true

		playAttackAnimation()

		-- Deal damage on animation event
		attackAnimTrack1:GetMarkerReachedSignal("Damage"):Connect(function()
			if (rootPart.Position - player.Character.HumanoidRootPart.Position).magnitude <= attackRange then
				dealDamage(player, damage.Value)
			end
		end)
		attackAnimTrack2:GetMarkerReachedSignal("Damage"):Connect(function()
			if (rootPart.Position - player.Character.HumanoidRootPart.Position).magnitude <= attackRange then
				dealDamage(player, damage.Value)
			end
		end)

		wait(attackCooldown)
		attacking = false
	end

	-- Function to chase the player
	local function chasePlayer(player)
		print("Enemy " .. enemy.Name .. " is chasing player: " .. player.Name)
		while player.Character and player.Character:FindFirstChild("HumanoidRootPart") and (rootPart.Position - player.Character.HumanoidRootPart.Position).magnitude <= chaseRange do
			humanoid:MoveTo(player.Character.HumanoidRootPart.Position)
			walkAnimTrack:Play()
			wait(0.1)

			if (rootPart.Position - player.Character.HumanoidRootPart.Position).magnitude <= attackRange then
				walkAnimTrack:Stop()
				attackPlayer(player)
			end
		end
		walkAnimTrack:Stop()
		print("Enemy " .. enemy.Name .. " stopped chasing player: " .. player.Name)
	end

	-- Main behavior loop
	while health.Value > 0 do
		local closestPlayer = nil
		local closestDistance = chaseRange + 1

		-- Find the closest player within chase range
		local playersInRange = getPlayersInRange(rootPart.Position, chaseRange)
		for _, player in pairs(playersInRange) do
			if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
				local distance = (rootPart.Position - player.Character.HumanoidRootPart.Position).magnitude
				if distance < closestDistance then
					closestPlayer = player
					closestDistance = distance
				end
			end
		end

		if closestPlayer then
			chasePlayer(closestPlayer)
		end

		wait(0.5)
	end
end

-- Start behavior for all enemies in the folder
for _, enemy in pairs(enemiesFolder:GetChildren()) do
	if enemy:IsA("Model") and enemy:FindFirstChildOfClass("Humanoid") and enemy:FindFirstChild("Animations") and enemy:FindFirstChild("Stats") then
		coroutine.wrap(handleEnemy)(enemy)
	else
		warn("Enemy model setup is incorrect:", enemy.Name)
	end
end

-- Handle newly added enemies
enemiesFolder.ChildAdded:Connect(function(child)
	if child:IsA("Model") and child:FindFirstChildOfClass("Humanoid") and child:FindFirstChild("Animations") and child:FindFirstChild("Stats") then
		coroutine.wrap(handleEnemy)(child)
	else
		warn("New enemy model setup is incorrect:", child.Name)
	end
end)

there are no errors in the output and everything looks fine to me.

1 Like

maybe because you are using math.huge, try another big number

For this case, if your enemy does not follow.

1.It can be due to your attack cooldown
2.change this (distance < closetdistance to distance <= closest distance)

3.it can be due to animations that cause it to not chase the player