The npc’s behavior is to runaway when the npc detects a gun. The logic works fine when its initially spawned but when it gets respawned it cant find the HumanoidRootPart and this is what prints in the output:
05:31:21.651 Infinite yield possible on ‘Civilian:WaitForChild(“HumanoidRootPart”)’ - Studio
05:31:21.652 Stack Begin - Studio
05:31:21.652 Script ‘Workspace.Civilian.AI’, Line 113 - function canSeePlayer - Studio
05:31:21.652 Script ‘Workspace.Civilian.AI’, Line 204 - Studio
05:31:21.652 Stack End - Studio
Respawn Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local civilianTemplate = ReplicatedStorage:WaitForChild("Civilian")
local spawnsFolder = Workspace:WaitForChild("Spawns")
-- Keep track of the civilians
local civilians = {}
local function resetCivilianBehavior(civilian)
-- Wait for Humanoid and HumanoidRootPart to ensure they're loaded
local humanoid = civilian:WaitForChild("Humanoid")
local humanoidRootPart = civilian:WaitForChild("HumanoidRootPart")
if not humanoidRootPart then
warn("HumanoidRootPart not found in resetCivilianBehavior!")
return
end
-- Reset health if the civilian has a Humanoid
humanoid.Health = humanoid.MaxHealth
-- Re-enable or reset custom scripts like FollowPlayerScript
for _, script in pairs(civilian:GetChildren()) do
if script:IsA("Script") or script:IsA("LocalScript") then
script.Disabled = true
script.Disabled = false
end
end
end
local function spawnCivilianAtPart(spawnPart)
-- Clone the Civilian from the template
local clonedCivilian = civilianTemplate:Clone()
-- Ensure the PrimaryPart is set before spawning
local humanoidRootPart = clonedCivilian:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
clonedCivilian.PrimaryPart = humanoidRootPart
else
warn("HumanoidRootPart is missing in the cloned civilian!")
return -- Exit the function early if no HumanoidRootPart exists
end
-- Set the cloned Civilian's position to the spawn part's position
clonedCivilian:SetPrimaryPartCFrame(spawnPart.CFrame)
-- Parent the cloned Civilian to the Workspace
clonedCivilian.Parent = Workspace
-- Reset the civilian's behavior or reinitialize scripts
resetCivilianBehavior(clonedCivilian)
-- Add the civilian to the civilians table for tracking
civilians[spawnPart] = clonedCivilian
-- Check if the civilian has a Humanoid to detect when it dies
local humanoid = clonedCivilian:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid.Died:Connect(function()
print("Civilian died! Checking parts before respawn...")
-- Before respawn, check if the necessary parts are missing
if not clonedCivilian:FindFirstChild("HumanoidRootPart") then
warn("HumanoidRootPart is missing before respawn!")
end
-- Destroy the previous civilian (clean up)
clonedCivilian:Destroy()
-- Wait a short time before spawning the next civilian at the same spot
wait(2)
spawnCivilianAtPart(spawnPart)
end)
end
end
-- Function to spawn civilians at all spawn parts
local function spawnCiviliansForAllParts()
local spawnParts = spawnsFolder:GetChildren()
if #spawnParts > 0 then
for _, spawnPart in ipairs(spawnParts) do
spawnCivilianAtPart(spawnPart)
end
else
warn("No spawn parts found in the Spawns folder!")
end
end
spawnCiviliansForAllParts()
NPC Script
local npc = script.Parent
local function canSeePlayer(player)
-- Add a timeout for the NPC's HumanoidRootPart
local humanoidRootPart = npc:WaitForChild("HumanoidRootPart")
if not humanoidRootPart then
warn("HumanoidRootPart not found in canSeePlayer function!")
return false -- Return false if the HumanoidRootPart isn't found
end
local playerHumanoidRootPart = player.Character:WaitForChild("HumanoidRootPart")
if not playerHumanoidRootPart then
warn("Player's HumanoidRootPart not found!")
return false
end
local npcPosition = humanoidRootPart.Position
local direction = (playerHumanoidRootPart.Position - npcPosition).unit
local ray = Ray.new(npcPosition, direction * 100)
local hit, position = workspace:FindPartOnRay(ray, npc)
return hit and hit:IsDescendantOf(player.Character)
end
local function onPlayerAdded(player)
player.CharacterAdded:Connect(function(character)
character.ChildAdded:Connect(function(child)
if child:IsA("Tool") and (child.Name == "Pistol" or child.Name == "AK-47") then
if not runningAway and canSeePlayer(player) then
runAwayFrom(player)
end
end
end)
character.ChildRemoved:Connect(function(child)
if child:IsA("Tool") and (child.Name == "Pistol" or child.Name == "AK-47") then
wait(runDelay)
runningAway = false
end
end)
end)
end