What do you want to achieve? Keep it simple and clear!
I want to create a Pathfinding script for my custom enemy to chase the player and attack them.
What is the issue? Include screenshots / videos if possible!
The pathfinding script is not working on the rig, and there are no errors in the outliner giving me a reason why. The animation script is working though.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I have tried swapping out the Humanoid with the AnimationController, I have tried looking up advice on how to help, However I fear that I may not find a full solition from that as my rig is custom made.
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
I am not sure if I am missing anything in terms of parenting the Humanoid to the HumanoidRootPart but I am very unsure why the script isn’t working. I am quite new to coding so I apologize if there are some dumb mistakes; I need use a tutorial to make the code.
Code Block is here I’m going to put the whole code so everyone can understand the veriables
-- Defining core veriables and services
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local Pathfinding = game:GetService("PathfindingService")
local crawler = script.Parent
local rig = crawler.Humanoid.Animator
local Root = crawler.HumanoidRootPart
-- Defining animations
local walkAni = script["Crawler Walk Animation"]
local idleAni = script["Crawler Idle Animation"]
local attackAni = script["Crawler Attack Animation"]
local Walk = rig:LoadAnimation(walkAni)
Walk.Priority = Enum.AnimationPriority.Movement
local Idle = rig:LoadAnimation(idleAni)
Idle.Looped = true
Idle.Priority = Enum.AnimationPriority.Idle
local Attack = rig:LoadAnimation(attackAni)
Attack.Priority = Enum.AnimationPriority.Action
-- Idle Start up animation
local function setup(): ()
Idle:Play()
end
setup()
-- Pathfinding Through RayCasting
local function checkForCharacter(character)
local rayOrigin = crawler:FindFirstChild("HumanoidRootPart").Position
local rayDirection = (character.HumanoidRootPart.Position - rayOrigin).Unit * 40
local rayResult = workspace:Raycast(rayOrigin, rayDirection, RaycastParams.new())
if rayResult then
local raycastIstance = rayResult.Instance
if raycastIstance:IsDescendantOf(character) then
return true
end
else
return false
end
end
local function findNearestPlay()
local players = Players:GetPlayers()
local nearestplayer = nil
local Maxdistance = 40
for _, player in pairs(players) do
if player.Character ~= nil then
local Targetplayer = player.Character
local distance = (crawler.HumanoidRootPart.Position - Targetplayer.HumanoidRootPart.Position).Magnitude
if distance < Maxdistance and checkForCharacter(Targetplayer) then
nearestplayer = Targetplayer
Maxdistance = distance
end
end
end
return nearestplayer
end
local function attack(character)
local distance = (crawler.HumanoidRootPart.Position - character.HumanoidRootPart.Position).Magnitude
if distance > 5 then
crawler.Humanoid:MoveTo(character.HumanoidRootPart.Position)
else
character.Humanoid.Health = 0
end
end
local function calculatePath(destination)
local agentParams = {
["AgentHeight"] = 4,
["AgentRadius"] = 6,
["AgentCanJump"] = false
}
local path = Pathfinding:CreatePath(agentParams)
path:ComputeAsync(Root.Position, destination)
return path
end
I will add a gif reference of what the enemy does as well here:
Damn you say that, it might be my problem. I suspect I need to call the fucnction calculatepath ti actually make it start calculating the rute and moving right?
--Bottom of script
while task.wait() do
local NearestPlayer = findNearestPlay()
if not NearestPlayer then continue end
local PlayerHRP = NearestPlayer.Character:FindFirstChild("HumanoidRootPart") :: BasePart
if not PlayerHRP then continue end
local Path = calculatePath(PlayerHRP.Position)
if Path.Status ~= Enum.PathStatus.Success then continue end
local WayPoints = Path:GetWaypoints()
for I, X in WayPoints do
hum:MoveTo(X.Position)
hum.MoveToFinished:Wait()
end
attack(NearestPlayer.Character)
end
Ok so I’ve tried adding this to the end of the code, for some reason it still didn’t work.
I tried going through a tutorial again and added a waypoint system of which I will add the code here. But the enemy only moves around the waypoints and not attack the player.
So I have a feeling that the attack function may not be working or I’ve dut something wrong in the code.
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local Pathfinding = game:GetService("PathfindingService")
local crawler = script.Parent
local rig = crawler.Humanoid.Animator
local Root = crawler.HumanoidRootPart
local function checkForCharacter(character)
local rayOrigin = crawler:FindFirstChild("HumanoidRootPart").Position
local rayDirection = (character.HumanoidRootPart.Position - rayOrigin).Unit * 40
local rayResult = workspace:Raycast(rayOrigin, rayDirection, RaycastParams.new())
if rayResult then
local raycastIstance = rayResult.Instance
if raycastIstance:IsDescendantOf(character) then
return true
end
else
return false
end
end
local function findNearestPlay()
local players = Players:GetPlayers()
local nearestplayer = nil
local Maxdistance = 40
for _, player in pairs(players) do
if player.Character ~= nil then
local Targetplayer = player.Character
local distance = (crawler.HumanoidRootPart.Position - Targetplayer.HumanoidRootPart.Position).Magnitude
if distance < Maxdistance and checkForCharacter(Targetplayer) then
nearestplayer = Targetplayer
Maxdistance = distance
end
end
end
return nearestplayer
end
local function attack(character)
local distance = (crawler.HumanoidRootPart.Position - character.HumanoidRootPart.Position).Magnitude
if distance > 5 then
crawler.Humanoid:MoveTo(character.HumanoidRootPart.Position)
else
character.Humanoid.Health = 0
end
end
local function calculatePath(destination)
local agentParams = {
["AgentHeight"] = 4,
["AgentRadius"] = 6,
["AgentCanJump"] = false
}
local path = Pathfinding:CreatePath(agentParams)
path:ComputeAsync(Root.Position, destination)
return path
end
local function walktToDestination(destination)
local path = calculatePath(destination)
if path.Status == Enum.PathStatus.Success then
for _, waypoint in pairs(path:GetWaypoints()) do
local nearestPlayer = findNearestPlay()
if nearestPlayer then
attack(nearestPlayer)
break
else
crawler.Humanoid:MoveTo(waypoint.Position)
crawler.Humanoid.MoveToFinished:Wait()
end
end
else
crawler.Humanoid:MoveTo(destination - (crawler.HumanoidRootPart.CFrame.LookVector * 10))
end
end
local function patrol()
local waypoints = workspace.Waypoints:GetChildren()
local randomNumber = math.random(1, #waypoints)
walktToDestination(waypoints[randomNumber].Position)
end
while task.wait(0.3) do
patrol()
end
Ok I seemed to have fixed all the error currently so don’t worry about the comment above. Turns out the HumanoidRootPart was just the wrong way round.
Code is kind of working, but the enemy seems to be stuck in a loop of wanting to chase but returning to the waypoints, also the enemy doesn’t damage the player
I managed to get it all fixed but thank you to both of you you’ve been super helpful and the override makes sense. I did a bit of sweaking but it works now. I just need to make the damage more stable now. I changed the for _, waypoints to a for index, waypoints and that seemed to work.