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.