Finally made tiny little agents work. OMG how many bugs remain, but I do have some progress.
navigation progress

Obvious bugs left:

  1. For some reason navigations work only in positive quadrent (+x, +y,+z)
  2. When higher obstacle is on the path, agents behave like it is small wall they can jump over. Looks like geometry is cut off, need to test this.
First thing I need to do now is navmesh debug display, so I could debug thing like this.

For the rest:
  1. UI integration of everything.
  2. API for all agent controls. Probably this comes above,
  3. Agent error handling, including removing/adding which is needed when velocity control is not enough.
  4. Implement all controls possible and non-physical agent. Physics based control will be implemented later (need to understand more things better for that 
  5. Implement distant path checks later, so targets beyond 256 polygons produce no errors.
But for now 1000 agents and no FPS drop. YAY!

Everything is in repository.

The script you can use to test code:

extends Spatial

# Declare member variables here. Examples:
# var a = 2
# var b = "text"

# Called when the node enters the scene tree for the first time.
var query
var filter
var crowd
const NUM_AGENTS = 100
func _ready():
 $DetourNavigationMeshInstance.collect_geometries(true)
 $DetourNavigationMeshInstance.build()
 query = DetourNavigationQuery.new()
 filter = DetourNavigationQueryFilter.new()
 query.init($DetourNavigationMeshInstance.get_navmesh(), $DetourNavigationMeshInstance.get_global_transform())
 var np = query.nearest_point(Vector3(100.0, 100.0, 100.0), Vector3(500.0, 500.0, 500.0), filter)
 var radius = 12
 for k in range (10):
  print(query.random_point_in_circle(np, radius, Vector3(500.0, 500.0, 500.0), filter))
 
 var path = query.find_path(Vector3(-100, 0, -100), Vector3(100, 0, 100), Vector3(500, 500, 500), filter)
 print(path)
 
 crowd = $DetourCrowdManager
 var nm = $DetourNavigationMeshInstance.get_navmesh()
 var positions = []
 var targets = []
 crowd.set_navigation_mesh(nm, $DetourNavigationMeshInstance.get_global_transform())
 crowd.set_max_agents(NUM_AGENTS + 1)
 crowd.set_max_agent_radius(2)
 for k in range(NUM_AGENTS):
  var tgt = query.random_point(filter)
  var pos = query.random_point(filter)
  while true:
   var ok = true
   for k in positions:
    if pos.distance_to(k) < 2.5:
     var p = Vector3(randf() - 0.5, 0, randf() - 0.5)
     var npv = p * 100
     npv.x = floor(npv.x) * 3.0
     npv.z = floor(npv.z) * 3.0
     pos = query.nearest_point(npv, Vector3(1500.0, 10.0, 1500.0), filter)
     ok = false
     break
   if ok:
    positions.append(pos)
    break
    
   
  var target = query.random_point(filter)
  var m = Spatial.new()
  add_child(m)
  m.translation = pos
  crowd.add_agent(m, 0)
  var capsule = CapsuleMesh.new()
  capsule.radius = 0.4
  capsule.mid_height = 1.0
  var capsule2 = CapsuleMesh.new()
  capsule2.radius = 0.1
  capsule2.mid_height = 0.3
  var mi = MeshInstance.new()
  mi.rotation.x = deg2rad(90)
  mi.translation = Vector3(0, 0.8, 0)
  var mi2 = MeshInstance.new()
  mi2.translation = Vector3(0, 0.8, -0.5)
  mi.set_mesh(capsule)
  m.add_child(mi)
  mi2.set_mesh(capsule2)
  m.add_child(mi2)
  crowd.set_agent_target_position(k, tgt)
  
var newt = 0.0
func _process(delta):
 newt += delta
 if newt > 5.0:
  filter = DetourNavigationQueryFilter.new()
  for k in range(NUM_AGENTS):
   crowd.set_agent_target_position(k, query.random_point(filter))
 
# crowd.set_target(query.random_point(filter))

# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass

A warning - I will rebase this branch to latest Godot master, so be careful - if you merge it, make sure you remove previous merge before merging it again. As thing shapes to the point when no serious changes happen, I will stop doing that, so wait a month before doing something serious.

All commit comments in github are welcome as well as issues.
You can send me your PRs if you want features added, I will rebase these myself if it is something interesting (email me or write me on IRC or discord)

Happy hacking!

Comments

Popular posts from this blog