I’ve attempted to switch up lines of codes, anchor and unanchor and so on, no solutions have by far worked. I seek to fix the problem where it doesn’t wan’t to walk off the ledge, its pretty annoying.
I am not going to use raycasting or any form of checking if the player is nearby to ignore using pathfinding due to there being dozens of NPCs at best, just don’t try assisting with this topic.
Help me, please, this is so bothersome and pathfinding is the worst thing to deal with.
If code is actually required, tell me.
Video for reference.
3 Likes
Just to clarify this is roblox pathfinding, not custom nor a free model. (the cars you see were me testing how smart the npc is when walking over obstacles) the red and blue ball are pathfinding links
Yes you may need some extra code
In your pathfinding script, add a table called agent parameters, these basically are some regulations for your path’s agent (your NPC in this case) eg. whether your agent can jump or run. While there are a couple of agent parameters, only two concern this issue. Add this piece of code:
local AgentParams = {
AgentCanJump = true
AgentCanClimb = true
}
local Path = game.PathfindingService:CreatePath(AgentParams)
EXPLANATION
By default, canjump and canclimb are set to false, so your agent (NPC) can’t jump or climb which may be why your NPC can’t fall off (I do see there’s a truss, which falls under canclimb criteria) because either one of them is preventing it from falling. If this doesn’t work then check out the pathfinding docs here for your own reference
I do have agent parameters in my code.
I’ve also tried finding solutions from the pathfinding documents, which did not work.
robloxapp-20240809-1627291.wmv (1.4 MB)
If you saw the video above, that was my own pathfinding script and the NPC did fall off the ledge (my path didn’t use any agent params). So it’s probably a problem with your npc or code
I can help you out with your code if you want me to
Yea I would appreciate it, how will you help anyways?
I’ll try and list out important pieces of code for you. Anyway, do you have a function where you ray cast to see if your NPC can see the player? If you do then you should probably comment it out.
I did list that i did not want any form of raycasting to detect NPCs seeing players.
simple awnser no i dont have raycasting
Could you like, show me your main code? I’ll try and see the parts you need to change
--((Services))
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService('Players')
local PathfindingService = game:GetService("PathfindingService")
--((Variables))
local SimplePath = require(ServerStorage.SimplePath)
local NPC = script.Parent
local Animator = NPC.Humanoid:FindFirstChild("Animator")
local Animation = ServerStorage.Anims.Attack
local AnimationLoaded = Animator:LoadAnimation(Animation)
local WooshSFX = NPC.HumanoidRootPart.Woosh
local Extraspeed = script.Parent:GetAttribute("AttackSlowdown")
--((Attack Function))
local function AttackFX()
WooshSFX:Play()
AnimationLoaded:Play()
end
for _,v in pairs(script.Parent:GetDescendants()) do
if (v:IsA("BasePart")) then
v:SetNetworkOwner(nil)
end
end
local AgentParams = {
AgentRadius = 2,
AgentHeight = 5,
WaypointSpacing = 3,
AgentCanJump = true,
AgentCanClimb = true
}
local path = PathfindingService:CreatePath(AgentParams)
local NearestPLR, NearestDist, NearestAttackDist, Damage = nil, nil, nil, nil
while task.wait() do
if NPC.Humanoid.Health > 0 then
NearestPLR, NearestDist, NearestAttackDist, Damage = nil, NPC:GetAttribute("SearchRange"), NPC:GetAttribute("AttackDistance"), NPC:GetAttribute("Damage")
for _, plr in workspace:GetChildren() do
if plr ~= nil then
if plr:FindFirstChild("IsPlayer") or plr:FindFirstChild("IsCore") then
local dist = (NPC.PrimaryPart.Position - plr.PrimaryPart.Position).Magnitude
if dist < NearestDist then
NearestPLR = plr
NearestDist = dist
if dist < NearestAttackDist then
AttackFX()
NPC.Humanoid.WalkSpeed = NPC.Humanoid.WalkSpeed - Extraspeed
task.wait(0.4)
local Coroutine = coroutine.wrap(function()
local dist2 = (NPC.PrimaryPart.Position - plr.PrimaryPart.Position).Magnitude
if dist2 < NearestAttackDist then
local hum = plr:FindFirstChild("Humanoid")
hum:TakeDamage(Damage)
end
NPC.Humanoid.WalkSpeed = NPC.Humanoid.WalkSpeed + Extraspeed
task.wait(1.5)
end)
Coroutine()
end
end
end
end
end
end
if NearestPLR ~= nil then
local function followPath()
local waypoints
local nextWaypointIndex
-- Compute the path
path:ComputeAsync(NPC.PrimaryPart.Position - Vector3.new(0, NPC.PrimaryPart.Size.Y/0.75, 0), NearestPLR.PrimaryPart.Position)
local function a()
for i, v in path:GetWaypoints() do
local part = Instance.new("Part")
part.Position = v.Position
part.Anchored = true
part.Parent = workspace.Debris
part.Material = "Neon"
part.BrickColor = BrickColor.new("Really red")
part.Size = Vector3.new(0.2,0.2,0.2)
part.CanCollide = false
task.wait(.1)
part:Destroy()
end
end
task.spawn(a)
waypoints = path:GetWaypoints()
nextWaypointIndex = 2
NPC.Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
NPC.Humanoid.MoveToFinished:Connect(function()
end)
end
followPath(NearestPLR.PrimaryPart.Position)
end
end
If you want me to shorten it into only the AI part, I’ll go ahead.
I don’t see any things blatantly wrong with your script. Try these however,
- Just remove the agent params temporarily and see if it makes a difference
- In the line
path:ComputeAsync(NPC.PrimaryPart.Position - Vector3.new(0, NPC.PrimaryPart.Size.Y/0.75, 0), NearestPLR.PrimaryPart.Position)
, remove the vector3 statement. Are you subtracting it to like, put the zombie on the ground?
It was someone else’s solution of a problem for their NPC and I was trying it, but it didn’t work.
Removing the Vector3 statement didn’t work.
Removing the agent parameters didn’t work, both of these didn’t work at all, what could be the problem?
I will show you my script, then see if they are any major diffs
(Im using OOP)
local PaOOP = {}
local players = game:GetService('Players')
local pathfindingService = game:GetService('PathfindingService')
PaOOP.__index = PaOOP
function PaOOP:new(bot : Model)
self = setmetatable({}, PaOOP)
self.bot = bot
return self
end
function PaOOP:CanSeeCharacter(player)
local rp = RaycastParams.new()
rp.FilterDescendantsInstances = {self.bot}
rp.FilterType = Enum.RaycastFilterType.Exclude
local hrp = self.bot.HumanoidRootPart
local ray = workspace:Raycast(hrp.Position,(player.Character.HumanoidRootPart.Position - hrp.Position).Unit * 100,rp)
if ray then
if ray.Instance:IsDescendantOf(player.Character) then
return true
else
return false
end
else
return false
end
end
function PaOOP:GetNearestPlayer(bpos: Vector3)
local sdist = 100
local np
for i, player in pairs(players:GetPlayers()) do
if not player.Character then continue end
local dist = (bpos - player.Character.HumanoidRootPart.Position).Magnitude
if dist <= sdist --[[and self:CanSeeCharacter(player)]] then
sdist = dist
np = player
end
end
return np
end
function PaOOP:TargetPlayer()
local path = pathfindingService:CreatePath()
local fwaypoints = workspace.Waypoints:GetChildren()
local player = self:GetNearestPlayer(self.bot.HumanoidRootPart.Position)
if player ~= nil then
path:ComputeAsync(self.bot.HumanoidRootPart.Position,player.Character.HumanoidRootPart.Position)
if path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
for i, w in pairs(waypoints) do
self.bot.Humanoid:MoveTo(w.Position)
end
else
self.bot.Humanoid:MoveTo(workspace.SpawnLocation.Position)
end
else
self.bot.Humanoid:MoveTo(fwaypoints[math.random(1,#fwaypoints)].Position)
self.bot.Humanoid.MoveToFinished:Wait()
end
end
return PaOOP
As you can see, I didn’t write a lot of code so I really can’t tell the issue with your script
Do you think it might be outside of the script? I can’t find what’s wrong with mine in any way.
Yours might be working due to raycasting, I cannot efficiently use raycasting to find the player if there are no obstacles due to my plans of having dozens of NPCs, what I mean is the raycasts will be blocked by the NPCs, and getting all the NPCs in the raycast parameters would lag the game a hefty amount as your possibly getting hundreds of parts each raycast. Unless you know a solution, I’m dumbfounded.
You could try and see if my problem occurs when you don’t raycast if possible.
It could be outside… maybe check your NPC, or you could try this (Its not clean but it kinda makes him fall off, it uses a ray)
for i,waypoint in path:GetWaypoints() do
if not workspace:Raycast(waypoint.Position, Vector3.new(0,-1,0)) then -- Make the direction as small as possible
NPC.PrimaryPart:ApplyImpulse(-(NPC.PrimaryPart.CFrame.RightVector) * 5) -- [[Its negative
right vector bc for some reason that is the front vector of HumRootPart]]--
end
end
Basically it raycast downwards from the waypoint and if there isn’t a ray (It doesn’t hit anything) then you force the NPC forwards, making him fall down)
Like I said, this isn’t very clean but it’s the only solution I can think of rn given the circumstances