Hello guys! I’m currently working on an entity-AI system, but I’ve had some trouble.
Script:
local pathfindingservice = game:GetService("PathfindingService")
local runservice = game:GetService("RunService")
local players = game:GetService("Players")
local npc = script.Parent
local humanoid = npc.Humanoid
local head = npc.Head
local hrp = npc.HumanoidRootPart
local settings = require(npc.Settings)
hrp:SetNetworkOwner(nil)
function findTarget()
local nearestTarget = nil
local nearestDistance = math.huge
for i,v in game.Players:GetPlayers() do
local character = v.Character
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if humanoid and humanoid.Health > 0 then
local Distance = (character.HumanoidRootPart.Position - hrp.Position).Magnitude
if Distance < nearestDistance then
if settings.checkTarget(character) then
nearestTarget = v
nearestDistance = Distance
return nearestTarget
end
end
end
end
end
function AttackTarget(target)
if target then
-- found target
local char = target.Character
else
warn("no target given.")
end
end
function targetAngle(character)
print("TARGETANGLE")
local npctocharacter = (character.HumanoidRootPart.Position-hrp.Position).Unit
local npclook = hrp.CFrame.LookVector
local dot = npctocharacter:Dot(npclook)
local maxdist = 100
local dist = (character.Head.Position-hrp.Position).Magnitude
local direction = (character.Head.Position-hrp.Position)
local params = RaycastParams.new()
params.FilterDescendantsInstances = {npc, character}
params.FilterType = Enum.RaycastFilterType.Exclude
local ray = workspace:Raycast(hrp.Position, direction*direction.Magnitude, params)
if ray and ray.Instance then
print("RAY TRUE")
print(ray.Instance.Name)
if dot > .5 then
print("DOT TRUE")
if dist <= maxdist then
-- char is in fov
print("DIST TRUE")
return true
else
return false
end
else
-- char is not in fov
return false
end
else
-- something is blocking the way
return false
end
end
function followTarget()
local target = findTarget()
if target then
if targetAngle(target.Character) then
print("followTarget")
local char = target.Character
local charhead = char.Head
local path = pathfindingservice:CreatePath(settings.agentparams)
path:ComputeAsync(hrp.Position, char.HumanoidRootPart.Position)
local waypoints = path:GetWaypoints()
humanoid.WalkSpeed = settings.MaxSpeed
if path.Status == Enum.PathStatus.Success then
for _, waypoint in pairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
else
warn("Path not found!")
end
end
end
end
function Patrol()
print("patrol")
humanoid.WalkSpeed = settings.PatrolSpeed
local patrolfolder = workspace.PatrolArea:GetChildren()
local randompatrol = patrolfolder[math.random(1,#patrolfolder)]
local path = pathfindingservice:CreatePath(settings.agentparams)
path:ComputeAsync(hrp.Position, randompatrol.Position)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for index, waypoint in pairs(waypoints) do
local target = findTarget()
if target then
followTarget()
else
if waypoint.Action == Enum.PathWaypointAction.Jump then
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
end
else
warn("Path not computed!", path.Status)
end
end
while task.wait() do
Patrol()
end
I’ve added some prints to understand where the bugs occurred, so please don’t mind those.
I’m having a difficult time comprehending my code, which is a bit embarrassing, but I’m left with no choice.
What I want it to do is find a player that is nearest to the entity, use pathfinding to attempt to attack them, which is blank for now, (I’ll add stuff soon.) The entity cannot detect the player in 3 ways,
- A direct ray must be established between the entity and the player so that the entity cannot see through objects.
- The entity can see through a limited angle.
- A maximum distance, so the entity cannot attack something that is extremely far.
So far, I’ve implemented all three, but the NPC is super buggy, as long as these requirements are met, I’m fine with changing the code.
I’ve tried to look for other solutions but I couldn’t find too much.
Any help is appreciated!