Intentional usage for named constructors


#1

I have AI ‘agents’ that spawn in the world with:

BP_Agent.spawn_at_xform(xform)

Turns out, I need them to know about the world’s navigation mesh, so I thought to add a named constructor to suit this purpose:

(RecastNavMesh nav_mesh) 
  [
    @navigation_mesh := nav_mesh
  ]

But, unexpectedly to me, you cannot just set an instance member like that in the named constructor. For if I change the named constructor to:

(RecastNavMesh nav_mesh) 
  [
    @navigation_mesh := nav_mesh
     println("set " @navigation_mesh)
  ]

it reads “set nil” even though the input is valid.

I noticed that the default constructor runs after the named constructor in this case, so I have to wonder if the instance member isn’t instantiated yet. There seems to be no way to set instance members with data ‘from the outside’ from within a default constructor. So I’m not sure what pattern to use to set instance members like this. For now, I’m just manually stuffing them myself after they are initialized, but as their needs grow more complex, it seems this ought to happen in a single place, at a determinable time, upon initialization.

Right now, I bunch up all of my agents in a list and spin through to ‘init’ them like:

agents.do[item.@navigation_mesh := @navigation_mesh]

And it does work just fine for now.

Am I missing something here?


#2

I think this is the problem. :ue4: is just going to blow you away with the default constructor since :ue4: does not support function overloading.

The recommended pattern for this is to use deferred spawning and set your relevant variables before you call finish spawning.

!p : GameLib.begin_deferred_actor_spawn_from_class(,class, t, ESpawnActorCollisionHandlingMethod.@@adjust_if_possible_but_always_spawn)<>BP_Agent
p.@navigation_mesh := nav_mesh
p : GameLib.finish_spawning_actor(p, t)

However for your case, navigation info is a world constant, so I’m wondering if @@world.@navigation_system already has what you need in there.