Hey there,
A while ago I’ve followed (and completed) a tutorial for a pathfinding, randomly walking enemy. Here’s the link to said tutorial:
However, what I’m trying to do now is to have the pathfinding NPC head from point A to point C, and still detect when it should attack a nearby player. Currently all the script achieves is heading from point A- to C, it doesn’t seem to detect when a player is nearby, and when it should attack accordingly.
I haven’t tried much yet as I couldn’t find all too much info for this topic, but any help is greatly appreciated!
Here’s the code:
math.randomseed(tick())
local myHuman = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")
local lowerTorso = script.Parent:WaitForChild("LowerTorso")
local walkAnim = script.Parent.Walk
local walkAnimPlay = myHuman:LoadAnimation(walkAnim)
local idleAnim = script.Parent.Idle
local idleAnimPlay = myHuman:LoadAnimation(idleAnim)
local holdWeapon = script.Parent.HoldWeapon
local holdWeaponPlay = myHuman:LoadAnimation(holdWeapon)
holdWeaponPlay:Play()
local clone = script.Parent:Clone()
function walkRandomly()
local goalA = script.Parent.Point1
local goalB = script.Parent.Point2
local goalC = script.Parent.Point3
repeat
idleAnimPlay:Stop()
myHuman:MoveTo(goalA.Position)
walkAnimPlay:Play()
myHuman.MoveToFinished:Wait()
idleAnimPlay:Play()
wait(math.random(2,6))
idleAnimPlay:Stop()
myHuman:MoveTo(goalB.Position)
walkAnimPlay:Play()
myHuman.MoveToFinished:Wait()
idleAnimPlay:Play()
wait(math.random(2,6))
idleAnimPlay:Stop()
myHuman:MoveTo(goalC.Position)
walkAnimPlay:Play()
myHuman.MoveToFinished:Wait()
idleAnimPlay:Play()
wait(math.random(2,6))
until
script.Parent.EnemyInSight.Value == true
end
function findPath(target)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position,target.Position)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
myHuman:MoveTo(waypoint.Position)
local timeOut = myHuman.MoveToFinished:Wait(1)
if not timeOut then
myHuman.Jump = true
-- print("Path too long!")
script.Parent.EnemyInSight.Value = false
findPath(target)
break
end
if checkSight(target) then
repeat
--- print("Moving directly to the target")
-- enemyInSight = true
myHuman:MoveTo(target.Position)
wait(0.1)
if target == nil then
break
elseif target.Parent == nil then
break
end
until checkSight(target) == false or myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
break
end
if (myRoot.Position - waypoints[1].Position).magnitude > 20 then
-- print("Target has moved, generating new path")
if script.Parent.EnemyInSight.Value == false then
script.Parent.EnemyInSight.Value = true
findPath(target)
break
end
end
end
end
end
function checkSight(target)
local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 40)
local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
if hit then
if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 3 then
script.Parent.EnemyInSight.Value = true
return true
end
end
return false
end
function findTarget()
local dist = script.Parent.Distance.Value
local target = nil
local potentialTargets = {}
local seeTargets = {}
for i,v in ipairs(workspace:GetChildren()) do
local human = v:FindFirstChild("Humanoid")
local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
if human and torso and v.Name ~= script.Parent.Name then
if (myRoot.Position - torso.Position).magnitude < dist and human.Health > 0 and human.NPC.Value == false then
table.insert(potentialTargets,torso)
end
end
end
if #potentialTargets > 0 then
for i,v in ipairs(potentialTargets) do
if checkSight(v) then
table.insert(seeTargets, v)
elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < dist then
script.Parent.EnemyInSight.Value = false
walkRandomly()
end
end
end
if #seeTargets > 0 then
dist = 30
for i,v in ipairs(seeTargets) do
if (myRoot.Position - v.Position).magnitude < dist then
target = v
dist = (myRoot.Position - v.Position).magnitude
end
end
end
if target then
if math.random(20) == 1 then
head.Quote1:Play()
end
end
return target
end
lowerTorso.Touched:Connect(function(obj)
if not obj.Parent:FindFirstChild("Humanoid") then
myHuman.Jump = true
end
end)
function main()
local target = findTarget()
if target then
myHuman.WalkSpeed = script.Parent.ChaseSpeed.Value
walkAnimPlay:Play()
findPath(target)
else
myHuman.WalkSpeed = script.Parent.WanderSpeed.Value
script.Parent.EnemyInSight.Value = false
walkRandomly()
end
end
while wait(0.1) do
if myHuman.Health < 1 then
break
end
main()
end
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.