I’ve watched a YT tutorial on how to make an npc follow the player, but I’m trying to modify it so that it only follows the player if it gets attacked by a player. So far I have done this, a script in the HumanoidRootPart of the NPC.
local Beam = game.Workspace.Beam
local npcHRP = script.Parent
local function GetNearestPlayer(minimumDistance)
local closestMagnitude = minimumDistance or math.huge
local closestPlayer
for i,v in next, game.Players:GetPlayers() do
local Character = v.Character
if (Character) then
local humanoid = Character.Humanoid
local HRP = Character.HumanoidRootPart
if (humanoid.Health > 0) then
local mag = (npcHRP.Position - HRP.Position).Magnitude
if (mag <= closestMagnitude) then
closestPlayer = v
closestMagnitude = mag
end
end
end
end
return closestPlayer
end
function ontouchedBeam(hit)
if hit == "Beam" then
GetNearestPlayer()
end
end
script.Parent.Touched:Connect(ontouchedBeam)
I’m not getting any errors, and I know it has something to do with
The problem isn’t with your GetNearestPlayer() function. It’s a standard iteration to find the closest player, although for i, v in pairs() is more commonly used than for i,v in next,
The hit variable in .Touched functions will always be a BasePart. The if hit == "Beam" then condition will never be satisfied because hit is not a string. print(hit) may display the string name of hit, but hit is still a part nonetheless.
I’m assuming you’re checking the name of hit against the string “Beam”, so you would use `if hit.Name == “Beam”.
local Beam = game.Workspace.Beam
local npcHRP = script.Parent
local function GetNearestPlayer(minimumDistance)
local closestMagnitude = minimumDistance or math.huge
local closestPlayer
for i,v in next, game.Players:GetPlayers() do
local Character = v.Character
if (Character) then
local humanoid = Character.Humanoid
local HRP = Character.HumanoidRootPart
if (humanoid.Health > 0) then
local mag = (npcHRP.Position - HRP.Position).Magnitude
if (mag <= closestMagnitude) then
closestPlayer = v
closestMagnitude = mag
end
end
end
end
return closestPlayer
end
function ontouchedBeam(hit)
if hit.Name == "Beam" then
GetNearestPlayer()
end
end
script.Parent.Touched:Connect(ontouchedBeam)
Could you further explain what it means for the player to “get attacked”?
Also, please use basic debugging strategies to further understand your problem before posting it to the devforum. Does the condition inside of ontouchedBeam ever become satisfied? You should always use print statements if you don’t know if sections of the code are running or not.
What exactly are you looking for with hit == "Beam"? Are you looking for a part named beam? A Beam instance (which won’t activate Touched events)?
GetNearestPlayer() in itself doesn’t do anything other than return a value. If you want the npc to actually move to that position, you will need to do Humanoid:MoveTo().
Wait, so if the beam instance wont activate touched events then how is this working?
Beam.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Enemy") then
print('Humanoid is taking damage!')
local humanoid = hit.Parent:FindFirstChild('Enemy')
humanoid.Health = humanoid.Health - damage
Beam:Destroy()
end
end)
In case you didn’t find solution or someone else comes across this that might need. The following works:
local Humanoid = script.Parent.Humanoid
function findNearestTorso(pos)
local list = game.Workspace:children()
local torso = nil
local dist = 100
local temp = nil
local human = nil
local temp2 = nil
for x = 1, #list do
temp2 = list[x]
if (temp2.className == "Model") and (temp2 ~= script.Parent) and temp2:FindFirstChild("Reward") == nil then
temp = temp2:findFirstChild("HumanoidRootPart")
human = temp2:findFirstChild("Humanoid")
if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
if (temp.Position - pos).magnitude < dist then
torso = temp
dist = (temp.Position - pos).magnitude
end
end
end
end
return torso
end
Humanoid:GetPropertyChangedSignal("Health"):Connect(function()
local healthChange = Humanoid.Health/Humanoid.MaxHealth
if Humanoid.Health >= 0 and Humanoid.Health <= Humanoid.MaxHealth then
while wait(2) do
local target = findNearestTorso(script.Parent.HumanoidRootPart.Position)
if target ~= nil then
script.Parent.Humanoid:MoveTo(target.Position, target)
end
end
end
end)
This will make npc follow nearest player only if npc health has changed.