Hello Developers,
I have a script which makes Bot follows the path but if Bot finds the target,
it chases the target. But my Bot is not usually able to detect some walls, and be stuck.
How can I make Bot smarter?
-- Scripted by FunnyDevGames
local MaxDistance = 100 -- Maximum distance Bot can find.
local CanWander = false -- If this is true, Bot will move to a random position based on WanderX and WanderZ when it doesn't find the target.
local WanderX, WanderZ = 10, 10
local CanMoveToPath = true -- If this is true, Bot will move along the set path when it doesn't find the target.
local Paths = workspace.Paths -- The parent folder of the paths that Bot will move to when CanMoveToPath is true.
-- Insert one or more BaseParts within the folder.
-- Do not use CanWander and CanMoveToPath at the same time.
-- It can move incorrectly.
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local Bot = script.Parent
local Humanoid = Bot.Humanoid
local HumanoidRootPart = Bot.HumanoidRootPart
local Chasing = false
local CanSoundPlay = true
local CanMove = true
local IsRunning = false
local StartTime = 0
local Path
local Waypoints
do
local function Raycast(PlayerCharacter, PlayerRootPart, Distance)
local NewRaycastParams = RaycastParams.new()
local FilterDescendantsInstances = {}
NewRaycastParams.FilterType = Enum.RaycastFilterType.Exclude
for _, Object in ipairs(Bot:GetDescendants()) do
if Object:IsA("BasePart") then
table.insert(FilterDescendantsInstances, Object)
end
end
for _, Object in ipairs(PlayerCharacter:GetDescendants()) do
if Object:IsA("BasePart") then
table.insert(FilterDescendantsInstances, Object)
end
end
NewRaycastParams.FilterDescendantsInstances = FilterDescendantsInstances
local RayDirection = PlayerRootPart.Position - HumanoidRootPart.Position
local RaycastResult = workspace:Raycast(HumanoidRootPart.Position, RayDirection, NewRaycastParams)
return if RaycastResult and Distance > 15 then true else false
end
local function CheckCondition(Player, PlayerCharacter, PlayerRootPart, AllDistance, Distance)
if (Distance <= MaxDistance) and not Raycast(PlayerCharacter, PlayerRootPart, Distance) then
AllDistance[Distance] = Player
end
end
local function GetNearestPlayer()
local AllDistance = {}
local Numbers = {}
Bot = script.Parent
Humanoid = Bot.Humanoid
HumanoidRootPart = Bot.HumanoidRootPart
for _, Player in ipairs(Players:GetPlayers()) do
local PlayerCharacter = Player.Character
if PlayerCharacter:FindFirstChild("Humanoid").Health > 0 and PlayerCharacter:FindFirstChild("Enemy") == nil and PlayerCharacter:FindFirstChild("ForceField") == nil then
local PlayerRootPart = PlayerCharacter:FindFirstChild("HumanoidRootPart")
local Distance = (HumanoidRootPart.Position - PlayerRootPart.Position).Magnitude
if CanSoundPlay then
CheckCondition(Player, PlayerCharacter, PlayerRootPart, AllDistance, Distance)
else
if tick() - StartTime >= 10 then
CheckCondition(Player, PlayerCharacter, PlayerRootPart, AllDistance, Distance)
else
AllDistance[Distance] = Player
end
end
end
end
for Distance in pairs(AllDistance) do
Numbers[#Numbers + 1] = Distance
end
if #Numbers == 0 then
return
end
local SmallestNumber = math.min(table.unpack(Numbers))
return AllDistance[SmallestNumber]
end
local function NotChasing()
IsRunning = true
if not (CanWander and CanMoveToPath) then
if CanWander then
while true do
task.wait()
if Chasing == false and Bot:FindFirstChild("Killing").Value == false then
local DestinationX, DestinationZ = HumanoidRootPart.Position.X + math.random(-WanderX, WanderX), HumanoidRootPart.Position.Z + math.random(-WanderZ, WanderZ)
Humanoid:MoveTo(Vector3.new(DestinationX, 0, DestinationZ))
task.wait(math.random(4, 6))
end
end
elseif CanMoveToPath then
local AllPaths = Paths:GetChildren()
if not (#AllPaths == 0) then
while true do
task.wait()
if Chasing == false and Bot:FindFirstChild("Killing").Value == false then
CanSoundPlay = true
StartTime = tick()
for _, AnimationTrack in ipairs(Humanoid:GetPlayingAnimationTracks()) do
AnimationTrack:Stop()
end
HumanoidRootPart.Ambience:Stop()
local RandomPath = AllPaths[math.random(1, #AllPaths)]
local TemporaryPath = PathfindingService:CreatePath({
AgentRadius = 2,
AgentHeight = 1.25,
AgentCanJump = true,
WaypointSpacing = 3,
Costs = {
Water = 25
}
})
TemporaryPath:ComputeAsync(HumanoidRootPart.Position, RandomPath.Position)
local TemporaryWaypoints = TemporaryPath:GetWaypoints()
for i = 1, #TemporaryWaypoints do
if not (i == #TemporaryWaypoints) then
local c = game.ServerStorage.Waypoint:Clone()
c.Position = TemporaryWaypoints[i].Position
c.Parent = workspace.Waypoints
else
local c = game.ServerStorage.LastWaypoint:Clone()
c.Position = TemporaryWaypoints[i].Position
c.Parent = workspace.Waypoints
end
end
if TemporaryPath and TemporaryWaypoints and TemporaryPath.Status == Enum.PathStatus.Success then
local RunAnimation = Humanoid.Animator:LoadAnimation(script.Parent.Animate:FindFirstChild("RunAnim", true))
RunAnimation:Play()
RunAnimation:AdjustSpeed(3)
for Index = 1, #TemporaryWaypoints do
Humanoid:MoveTo(TemporaryWaypoints[Index].Position)
if TemporaryWaypoints[Index].Action == Enum.PathWaypointAction.Jump then
task.wait(0.25)
Humanoid.Jump = true
end
Humanoid.MoveToFinished:Wait()
end
workspace.Waypoints:ClearAllChildren()
RunAnimation:Stop()
script.Parent.Animate.Enabled = true
end
end
end
else
error("No path exists!")
end
end
else
error("Cannot use both function!")
end
end
while true do
task.wait()
pcall(function()
local NearestPlayer = GetNearestPlayer()
if NearestPlayer and CanMove then
if CanSoundPlay then
CanSoundPlay = false
HumanoidRootPart.Spotted:Play()
HumanoidRootPart.Ambience:Play()
StartTime = tick()
end
Chasing = true
CanMove = false
script.Parent.Animate.Enabled = true
Path = PathfindingService:CreatePath({
AgentRadius = 2,
AgentHeight = 1.25,
AgentCanJump = true,
WaypointSpacing = 3,
Costs = {
Water = 25
}
})
Path:ComputeAsync(HumanoidRootPart.Position, NearestPlayer.Character:FindFirstChild("HumanoidRootPart").Position)
Waypoints = Path:GetWaypoints()
for i = 1, #Waypoints do
if not (i == #Waypoints) then
local c = game.ServerStorage.Waypoint:Clone()
c.Position = Waypoints[i].Position
c.Parent = workspace.Waypoints
task.spawn(function()
task.wait(0.1)
c:Destroy()
end)
else
local c = game.ServerStorage.LastWaypoint:Clone()
c.Position = Waypoints[i].Position
c.Parent = workspace.Waypoints
task.spawn(function()
task.wait(0.1)
c:Destroy()
end)
end
end
if Path and Waypoints and Path.Status == Enum.PathStatus.Success then
Humanoid:MoveTo(Waypoints[3].Position)
if Waypoints[3].Action == Enum.PathWaypointAction.Jump then
task.spawn(function()
task.wait(0.25)
Humanoid.Jump = true
end)
end
elseif Path.Status == Enum.PathStatus.NoPath then
Humanoid:MoveTo(NearestPlayer.Character.PrimaryPart.Position)
end
elseif not NearestPlayer then
Chasing = false
if CanWander or CanMoveToPath then
Path = nil
Waypoints = nil
if CanMoveToPath then
script.Parent.Animate.Enabled = false
end
if not IsRunning then
task.spawn(NotChasing)
end
Humanoid.MoveToFinished:Wait()
end
end
CanMove = true
end)
end
end
Any responses and feedback be appreciated!