Currently working on a skinned mesh NPC. I have it set up to detect when a player gets within chase range to start the chase and attack behavior. I’ve tried everything i know but for some reason all i keep getting in the out is “Skeleton did not detect any players”
local Players = game:GetService("Players")
local AnimationHandler = require(script.Parent.AnimationHandler)
local BehaviorHandler = {}
-- Range and behavior settings
local attackRange = 5
local chaseRange = 20
local wanderRadius = 10
local wanderDelay = 10
-- Detect the closest player within chaseRange (for skinned mesh support)
function BehaviorHandler:DetectPlayers(enemy)
local closestPlayer = nil
local closestDistance = chaseRange
print("Checking for players near enemy:", enemy.Name)
-- Attempt to use PrimaryPart first, fallback to GetPivot if necessary
local enemyPosition
if enemy.PrimaryPart then
enemyPosition = enemy.PrimaryPart.Position
print("Enemy position (using PrimaryPart):", enemyPosition)
else
enemyPosition = enemy:GetPivot().Position
print("Enemy position (using GetPivot()):", enemyPosition)
end
-- Player detection loop
for _, player in pairs(Players:GetPlayers()) do
local character = player.Character
if character then
print("Checking player:", player.Name)
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
local humanoid = character:FindFirstChild("Humanoid")
if humanoidRootPart and humanoid then
print(player.Name .. " has HumanoidRootPart and Humanoid.")
if humanoid.Health > 0 then
print(player.Name .. " is alive.")
-- Calculate distance
local playerPosition = humanoidRootPart.Position
local distance = (playerPosition - enemyPosition).Magnitude
print("Player position:", playerPosition)
print("Distance between " .. enemy.Name .. " and " .. player.Name .. ":", distance)
-- Update closest player if within range
if distance <= closestDistance then
closestPlayer = player
closestDistance = distance
print("Closest player updated to:", player.Name)
end
else
print(player.Name .. " is not alive.")
end
else
print(player.Name .. " is missing HumanoidRootPart or Humanoid.")
end
else
print(player.Name .. " does not have a character.")
end
end
if closestPlayer then
print(enemy.Name .. " detected player:", closestPlayer.Name, "at distance:", closestDistance)
else
print(enemy.Name .. " did not detect any players.")
end
return closestPlayer
end
-- Chase the detected player (for skinned mesh models)
function BehaviorHandler:ChasePlayer(enemy, player, animationTracks)
local humanoid = enemy:FindFirstChild("Humanoid")
if not humanoid then
warn("Humanoid missing for enemy:", enemy.Name)
return
end
-- Use PrimaryPart or GetPivot for enemy position
local rootPart = enemy.PrimaryPart or enemy:GetPivot()
local playerRootPart = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
if not playerRootPart then
warn("Player HumanoidRootPart missing.")
return
end
print(enemy.Name .. " is chasing player:", player.Name)
while player.Character and player.Character:FindFirstChild("HumanoidRootPart") and player.Character.Humanoid.Health > 0 do
local enemyPosition = (enemy.PrimaryPart and enemy.PrimaryPart.Position) or enemy:GetPivot().Position
local distance = (enemyPosition - playerRootPart.Position).Magnitude
if distance <= chaseRange then
humanoid:MoveTo(playerRootPart.Position)
AnimationHandler:PlayAnimation(animationTracks, "Run")
if distance <= attackRange then
print(enemy.Name .. " is attacking player:", player.Name)
humanoid:MoveTo(enemyPosition) -- Stop moving
AnimationHandler:PlayAnimation(animationTracks, "Attack")
task.wait(animationTracks["Attack"].Length)
return
end
else
print(player.Name .. " moved out of chase range.")
break
end
task.wait(0.1)
end
AnimationHandler:StopAnimation(animationTracks, "Run")
end
-- Enemy wandering behavior (for skinned mesh models)
function BehaviorHandler:Wander(enemy, animationTracks)
local humanoid = enemy:FindFirstChild("Humanoid")
if not humanoid then
warn("Humanoid missing for enemy:", enemy.Name)
return
end
-- Use PrimaryPart or GetPivot for proper movement
print(enemy.Name .. " is wandering.")
while true do
local wanderPosition
if enemy.PrimaryPart then
wanderPosition = enemy.PrimaryPart.Position + Vector3.new(math.random(-wanderRadius, wanderRadius), 0, math.random(-wanderRadius, wanderRadius))
else
wanderPosition = enemy:GetPivot().Position + Vector3.new(math.random(-wanderRadius, wanderRadius), 0, math.random(-wanderRadius, wanderRadius))
end
humanoid:MoveTo(wanderPosition)
AnimationHandler:PlayAnimation(animationTracks, "Walk")
humanoid.MoveToFinished:Wait()
AnimationHandler:StopAnimation(animationTracks, "Walk")
AnimationHandler:PlayAnimation(animationTracks, "Idle")
task.wait(wanderDelay)
end
end
return BehaviorHandler