Dont really know how to use pathfinding efficiently so im coming here to find out how i can do stuff better and fix some bugs
- How do i visualize paths better?, as currently im just creating a part per waypoint, which isnt the best as shown here
- What do i do about it jumping?, didnt know how to make it jump correctly and tried following some solution that other players had and uh
-
What happens if i call a MoveTo if theres already one active? Basically what if i wanted the bot to wander around if no players are withing a certain distance, and during the wander it spots a player? (Already got the players distance and stuff).
-
What can i do to combat the jittering / lagging behind as shown
- how come the {Costs} do not work?, i have it set up, but the nextbot just decides instead of avoiding the wall it should avoid, it goes straight through it.
Heres the code
local Players = game.Players
local DisableAllBots = false
local Debug = true
local PathFindingService = game:GetService("PathfindingService")
local RunService = game:GetService("RunService")
local function FindNearest(NBC)
local NearestPlayer
local NearestDistance
for _, Player in (Players:GetPlayers()) do
if Player.Character and Player.Character.Humanoid and Player.Character.Humanoid.Health ~= 0 then
local Mag = (Player.Character.HumanoidRootPart.Position - NBC.Position).Magnitude
if Player.Character.IsInSafeZone == false then
if NearestDistance then
if Mag < NearestDistance then NearestDistance = Mag; NearestPlayer = Player.Character end
else
NearestDistance = Mag; NearestPlayer = Player.Character
end
end
end
end
return NearestPlayer, NearestDistance
end
local function pfm(NextBot)
local Path = PathFindingService:CreatePath({
['AgentRadius'] = 5,
['AgentHeight'] = 5,
['AgentCanJump'] = true,
['WaypointSpacing'] = 3,
Costs = {
Water = 20,
SmoothPlastic = 1,
ForceField = math.huge,
Untouchable = math.huge
}
})
local Waypoints
local NextWaypointIndex
local reachedConnection
local blockedConnection
local NearestPlr, NearestDistance = FindNearest(NextBot.Character)
if not NearestPlr or NearestDistance > NextBot.ChangeableValues.DetectionDistance.Value then
return "No Near Players"
else
local Yes, No = pcall(function()
Path = PathFindingService:FindPathAsync(NextBot.PrimaryPart.Position, NearestPlr.HumanoidRootPart.Position)
end)
if Yes and Path.Status == Enum.PathStatus.Success then
Waypoints = Path:GetWaypoints()
blockedConnection = Path.Blocked:Connect(function(BwI)
if BwI >= NextWaypointIndex then
blockedConnection:Disconnect()
pfm(NextBot)
end
end)
for i, v in ipairs(Waypoints) do
if v.Action == Enum.PathWaypointAction.Jump then
NextBot.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
local Part = Instance.new("Part", workspace.Extras)
Part.Shape = Enum.PartType.Ball
Part.Size = Vector3.new(1,1,1)
Part.Anchored = true
Part.Position = v.Position
Part.Material = Enum.Material.Neon
Part.Color = Color3.new(0,4,0)
Part.CanCollide = false
Part.Transparency = 0.5
NextBot.Humanoid:MoveTo(v.Position)
NextBot.Humanoid.MoveToFinished:Wait()
end
else
warn("Failed To Compute A Valid Path, Did you make sure that the NextBot Isnt Trapped / Stuck?: " .. if No then No else "Nil")
end
end
end
local function PathFindingMovement(NextBot)
local Run
Run = RunService.Heartbeat:Connect(function(DT)
if NextBot.Humanoid.Active.Value == true and DisableAllBots == false then
local D = pfm(NextBot)
if D and Debug == true then
print(D)
end
else
Run:Disconnect()
end
end)
end
Unedited Code
-- The NextBot Handler Module --
local Players = game.Players
local DisableAllBots = false
local Debug = true
local PathFindingService = game:GetService("PathfindingService")
local RunService = game:GetService("RunService")
-- Functions
local function FindNearest(NBC)
local NearestPlayer
local NearestDistance
for _, Player in (Players:GetPlayers()) do
if Player.Character and Player.Character.Humanoid and Player.Character.Humanoid.Health ~= 0 then
local Mag = (Player.Character.HumanoidRootPart.Position - NBC.Position).Magnitude
if Player.Character.IsInSafeZone == false then
if NearestDistance then
if Mag < NearestDistance then NearestDistance = Mag; NearestPlayer = Player.Character end
else
NearestDistance = Mag; NearestPlayer = Player.Character
end
end
end
end
return NearestPlayer, NearestDistance
end
local function MoveToMovement(NextBot, ValFol)
local Stepped
local NearestPlayer, NearestDistance
Stepped = RunService.Heartbeat:Connect(function(DTime)
if NextBot.Humanoid.Active.Value == true then
NearestPlayer, NearestDistance = FindNearest(NextBot.Character)
if NearestPlayer and NearestDistance then
if NearestDistance <= ValFol.DetectionDistance.Value then
NextBot.Humanoid:MoveTo(NearestPlayer.HumanoidRootPart.Position)
end
end
else
Stepped:Disconnect()
end
end)
end
local function pfm(NextBot)
local Path = PathFindingService:CreatePath({
['AgentRadius'] = 5,
['AgentHeight'] = 5,
['AgentCanJump'] = true,
['WaypointSpacing'] = 3,
Costs = {
Water = 20,
SmoothPlastic = 1,
ForceField = math.huge,
Untouchable = math.huge
}
})
local Waypoints
local NextWaypointIndex
local reachedConnection
local blockedConnection
local NearestPlr, NearestDistance = FindNearest(NextBot.Character)
if not NearestPlr or NearestDistance > NextBot.ChangeableValues.DetectionDistance.Value then
return "No Near Players"
else
local Yes, No = pcall(function()
Path = PathFindingService:FindPathAsync(NextBot.PrimaryPart.Position, NearestPlr.HumanoidRootPart.Position)
end)
if Yes and Path.Status == Enum.PathStatus.Success then
Waypoints = Path:GetWaypoints()
blockedConnection = Path.Blocked:Connect(function(BwI)
if BwI >= NextWaypointIndex then
blockedConnection:Disconnect()
pfm(NextBot)
end
end)
for i, v in ipairs(Waypoints) do
if v.Action == Enum.PathWaypointAction.Jump then
NextBot.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
local Part = Instance.new("Part", workspace.Extras)
Part.Shape = Enum.PartType.Ball
Part.Size = Vector3.new(1,1,1)
Part.Anchored = true
Part.Position = v.Position
Part.Material = Enum.Material.Neon
Part.Color = Color3.new(0,4,0)
Part.CanCollide = false
Part.Transparency = 0.5
NextBot.Humanoid:MoveTo(v.Position)
NextBot.Humanoid.MoveToFinished:Wait()
end
else
warn("Failed To Compute A Valid Path, Did you make sure that the NextBot Isnt Trapped / Stuck?: " .. if No then No else "Nil")
end
end
end
local function PathFindingMovement(NextBot)
local Run
Run = RunService.Heartbeat:Connect(function(DT)
if NextBot.Humanoid.Active.Value == true and DisableAllBots == false then
local D = pfm(NextBot)
if D and Debug == true then
print(D)
end
else
Run:Disconnect()
end
end)
end
-- Module
local Nbot = {}
Nbot.Setup = function(NextBot)
NextBot.PrimaryPart:SetNetworkOwner(nil)
local ValFol = NextBot.ChangeableValues
local NextBotSpeed = ValFol.Speed.Value
local NextBotJumpPower = ValFol.JumpPower.Value
local NextBotHealth = ValFol.Health.Value
local CanBeKilled = ValFol.CanBeKilled.Value
local Pic = ValFol.Image.Value
local NBotHumanoid = NextBot.Humanoid
NBotHumanoid.WalkSpeed = NextBotSpeed
NBotHumanoid.JumpPower = NextBotJumpPower
if CanBeKilled == true then
NBotHumanoid.MaxHealth = NextBotHealth; NBotHumanoid.Health = NextBotHealth
else
local ff = Instance.new("ForceField", NextBot)
ff.Visible = false
NBotHumanoid.MaxHealth = math.huge; NBotHumanoid.Health = math.huge
end
NextBot.Character.Front.ImageLabel.Image = "rbxassetid://" .. Pic
NextBot.Character.Back.ImageLabel.Image = "rbxassetid://" .. Pic
if not NextBot.Humanoid:GetAttribute("Active") then
NextBot.Humanoid:SetAttribute("Active", false)
end
return "Setup Complete"
end
Nbot.Start = function(NextBot)
local ValFol = NextBot.ChangeableValues
NextBot.Humanoid.Active.Value = true
if ValFol.SmartAi.Value == true then
PathFindingMovement(NextBot)
print("Smart Movement Activated")
else
MoveToMovement(NextBot, ValFol)
print("Basic Movement Activated")
end
end
Nbot.Stop = function(NextBot)
NextBot.Humanoid.Active.Value = false
end
Nbot.DisableAllBots = function(A)
if A then
print("This function doesnt require anything to be sent, disables all bots")
end
if DisableAllBots == true then
print("Bots are already disabled")
return "Failed, Bots Are Disabled Already"
end
DisableAllBots = true
return "Bots Disabled"
end
Nbot.EnableAllBots = function(A)
if A then
print("This function doesnt require anything to be sent, enables all bots")
end
if DisableAllBots == false then
print("Bots are already enabled")
return "Failed, Bots Are Enabled Already"
end
DisableAllBots = false
return "Bots Enabled"
end
return Nbot