Nextbot attempts to avoid small inclines as if it were marked avoid, but isn't.
4 replies, posted
So I made a nextbot NPC, and the picture below represents what happens when they try to walk over a small gap, they typically walk on the white line, stop, walk along it, rarely cross, and when they do it is at the flat part, so it is probably something to do with the splice navmesh.
https://files.facepunch.com/forum/upload/110731/30a4876c-8d69-4c8a-ab9f-33d833393acd/rp_venator_extensive0003.jpg
It is quite odd, I have the code just in case it has to do with RunBehavoir, otherwise, my guess is they are scared of the spliced navmesh.
AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
include("shared.lua")
local modelselect =
{
"models/player/smitty/bf2_reg/sm_327th_trooper/sm_327th_trooper.mdl",
"models/player/smitty/bf2_reg/501st_trooper/501st_trooper.mdl",
"models/player/smitty/bf2_reg/st_trooper/st_trooper.mdl",
"models/keriox/104th_trooper/104th_trooper.mdl",
"models/player/smitty/bf2_reg/blue_pilot_trooper/blue_pilot_trooper.mdl",
"models/player/smitty/bf2_reg/red_pilot_trooper/red_pilot_trooper.mdl",
"models/player/smitty/bf2_reg/gold_pilot_trooper/gold_pilot_trooper.mdl",
"models/player/smitty/bf2_reg/jt_medic_trooper/jt_medic_trooper.mdl",
"models/player/smitty/bf2_reg/sm_ct_trooper/sm_ct_trooper.mdl",
"models/player/smitty/bf2_reg/sm_212th_trooper/sm_212th_trooper.mdl"
}
function ENT:Initialize()
self.Saluting = false
self:SetModel(modelselect[math.random(1, #modelselect)])
self:SetHealth(15000000000000)
self:SetUseType(SIMPLE_USE)
self.loco:SetStepHeight(18)
self.loco:SetJumpHeight(58)
self:AddFlags(FL_CLIENT)
self:SetCollisionBounds( Vector(-4,-4,0), Vector(20,25,64) )
timer.Simple(math.random(600,900),function()
if IsValid(self) then
local navs = navmesh.Find(self:GetPos(), 6000, 40, 40)
local nav = navs[math.random(1,#navs)]
local pos = nav:GetRandomPoint()
if !IsValid(nav) then return end
if IsValid(self) then
self:Remove()
else return end
entity = ents.Create("nextbot")
entity:SetPos(pos)
if IsValid(nav) then
entity:Spawn()
elseif !IsValid(nav) or nav:HasAttributes(128) then
nav:GetRandomPoint()
entity = ents.Create("nextbot")
entity:SetPos(pos)
end
end
end)
end
util.AddNetworkString("Salute")
function ENT:RunBehaviour()
while ( true ) do -- Here is the loop, it will run forever
if self.Saluting then
coroutine.wait(3)
end
local navs = navmesh.Find(self:GetPos(), math.random(700,1000), 40, 40)
local nav = navs[math.random(1,#navs)]
local pos = nav:GetRandomPoint()
self:StartActivity( ACT_WALK ) -- Walk animation
self.loco:SetDesiredSpeed( 100 ) -- Walk speed
if !IsValid(nav) then return end
if IsValid(nav) or nav:HasAttributes(NAV_MESH_STAIRS) then
self:MoveToPos( pos, { tolerance = (math.random(25,50)), maxage = math.random(500, 1000), lookahead = 1000, draw = false})
if self.loco:IsStuck() or !IsValid(nav) then
self:MoveToPos( pos, { tolerance = (math.random(25,45)), maxage = 30, lookahead = 100})
end
end
if ( self.loco:IsStuck() ) then
self:HandleStuck();
if IsValid(nav) then
self:MoveToPos( pos, { tolerance = (math.random(0,20)), maxage = math.random(350, 500), lookahead = 600})
end
return "stuck"
end
self:StartActivity( ACT_IDLE ) -- Idle animation
if self.Saluting then --Pauses
coroutine.wait(2.75)
elseif not self.Saluting then
coroutine.wait(math.random(1.25,2.5))
end
coroutine.yield() -- The function is done here, but will start back at the top of the loop and make the bot walk somewhere else
end
end
function ENT:Think()
if ( SERVER ) then -- Only set this stuff on the server
self:NextThink( CurTime() ) -- Set the next think for the serverside hook to be the next frame/tick
return true -- Return true to let the game know we want to apply the self:NextThink() call
end
end
if ( SERVER ) then -- This hook is only available on the server
function ENT:Use( activator, caller ) -- If a player uses this entity, play an animation
if (!self.Saluting) then
self:StartActivity(ACT_GMOD_TAUNT_SALUTE) -- Play the open sequence
self.Saluting = true -- We are now opened
self.loco:SetDesiredSpeed(0)
self.loco:FaceTowards(Vector(caller:GetPos()))
self:EmitSound( Sound( "npc/combine_soldier/vo/affirmative2.wav" ), 75, 100, .3, CHAN_AUTO )
net.Start("Salute")
net.Send(caller)
timer.Simple(3, function()
self.loco:SetDesiredSpeed(100)
self:StartActivity(ACT_WALK)
self.Saluting = false
end)
end
end
end
function ENT:OnContact( ent )
if (tostring(ent:GetClass()) == "nextbot") or ent:IsPlayer() then
self:SetPos( self:GetPos() + Vector( math.Rand( -1, 1 ), math.Rand( -1, 1 ), 0 ) * 3 )
end
end
hook.Add( "Think", "OpenDoors", function()
for k,_ in pairs( ents.FindByClass("nextbot") ) do
local ents = ents.FindInSphere(_:GetPos(), 40)
for k,v in pairs(ents) do
if v:GetClass() == "prop_door_rotating" or v:GetClass() == "func_door" then
v:Fire("Open")
end
end
end
end)
Thanks if you can help.
See those cyan lines that connect the areas in the navmesh? Those indicate "one way" connections. To make them to way, you need to tell next bots that they can go from one area to the other AND back. Highlight the other area with your cursor, `nav_select`, mouse over the current area, `nav_connect`, you should see the cyan line go blue. When you do, `nav_save`. I've been meaning to write a tutorial on navmeshes since there's so little documentation. I just can't seem to find the time...
Cyan is two way, dark blue is one way, I'll try disconnecting and reconnecting them anyway tho.
You're right, my bad. Can you turn the path drawing on so we can see where they think they should go?
self:MoveToPos( pos, { tolerance = (math.random(25,50)), maxage = math.random(500, 1000), lookahead = 1000, draw = true})
I will later, but for now, the draw path literally just either stops on the line and then goes along it, or it just stops short of it, then turns around.
Sorry, you need to Log In to post a reply to this thread.