First, I’m sorry for my poor English skills. This is my first time working on AI Pathfinding, and I do not know about this. But I need to make an Enemy for my game, and I have some problems.
The problem is that Pathfinding doesn’t work as I need it to. NPC gets stuck, and the Visualize looks Messy (I use SimplePath - Pathfinding Module)
I watch a lot of YouTube tutorials, but they don’t seem to go well with my script, or I am just a dumb
This is the Code I use
-- --- {Properties}
local Properties = {
--- Chase
targetDistance = 50,
CloseTargetDistance = 10,
stopDistance = 2.5,
--- Attack
CloseAttackDistance = 10,
RageAttackDistance = 17,
AttackCooldown = 1,
}
--- {Services}
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")
local TweenService = game:GetService("TweenService")
--- {Module}
local SimplePath = require(game.ReplicatedStorage.Module.SimplePathModule)
--- {NPC Variables}
local NPC = script.Parent
local HRP = NPC.HumanoidRootPart
local Humanoid = NPC.Humanoid
HRP:SetNetworkOwner(nil)
local LastAttack = tick()
--- {Animation}
local animator = Humanoid:WaitForChild("Animator")
local idleAnim = game.ReplicatedStorage.Animation.Enemy.Test:WaitForChild("Idle")
local walkAnim = game.ReplicatedStorage.Animation.Enemy.Test:WaitForChild("Walk")
local SeekAnim = game.ReplicatedStorage.Animation.Enemy.Test:WaitForChild("Seek")
local idleTrack = animator:LoadAnimation(idleAnim)
local walkTrack = animator:LoadAnimation(walkAnim)
local SeekTrack = animator:LoadAnimation(SeekAnim)
idleTrack:Play()
--- {Pathfinding, RayCasting}
local pathParams = {
AgentHeight = 2,
AgentRadius = 3,
AgentCanJump = false,
}
local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
rayParams.FilterDescendantsInstances = {NPC}
local PathDB = false
function CanSeeTarget(Target)
local Origin = HRP.Position
local direction = (Target.HumanoidRootPart.Position - HRP.Position).Unit * Properties.targetDistance
local ray = workspace:Raycast(Origin, direction, rayParams)
if ray and ray.Instance then
if ray.Instance:IsDescendantOf(Target) then
return true
else
return false
end
else
return false
end
end
function NearestTarget()
local playerList = Players:GetPlayers()
local maxDistance = Properties.targetDistance
local nearestPlayer
local direction
local distance
for _, player in pairs(playerList) do
if player.Character then
local distanceVector = (player.Character.HumanoidRootPart.Position - HRP.Position)
local target = player.Character
local Gotdistance = (player.Character.HumanoidRootPart.Position - HRP.Position).Magnitude
if Gotdistance < maxDistance and CanSeeTarget(target) then
nearestPlayer = target
distance = distanceVector.Magnitude
direction = distanceVector.Unit
end
end
end
return nearestPlayer, distance, direction
end
local function pathFindTo(nearestPlayer)
local path = SimplePath.new(NPC, pathParams)
path.Visualize = true
path:Run(nearestPlayer.HumanoidRootPart.Position)
end
function FoundTarget(nearestPlayer, distance, direction, path)
pathFindTo(nearestPlayer)
if distance <= Properties.CloseAttackDistance and tick() - LastAttack >= Properties.AttackCooldown then
LastAttack = tick()
print("Close")
elseif distance > Properties.CloseAttackDistance and distance <= Properties.RageAttackDistance and tick() - LastAttack >= Properties.AttackCooldown then
LastAttack = tick()
print("Rage")
end
end
function LostTarget(nearestPlayer, distance, direction)
if walkTrack.IsPlaying then
walkTrack:Stop()
end
Humanoid:Move(Vector3.new())
end
RunService.Heartbeat:Connect(function()
local nearestPlayer, distance, direction = NearestTarget()
if nearestPlayer then
local NPCLook = NPC.Head.CFrame.LookVector
local dotProduct = direction:Dot(NPCLook)
if distance <= Properties.targetDistance and dotProduct > 0.5 and distance >= Properties.stopDistance then
FoundTarget(nearestPlayer, distance, direction)
elseif distance <= Properties.CloseTargetDistance and distance >= Properties.stopDistance then
FoundTarget(nearestPlayer, distance, direction)
else
LostTarget(nearestPlayer, distance, direction)
end
end
end)
Humanoid.Running:Connect(function(movespeed)
if movespeed <= 0 then
if walkTrack.IsPlaying then
walkTrack:Stop()
end
else
if not walkTrack.IsPlaying then
walkTrack:Play()
end
end
end)
