NodeCanvas Forums › Support › [Bug] Async graph loading incompatible with object pooling?
I’ve started to pool my graphs.
One thing I’ve noticed is that if I use an FSM, and its First Activation is set to async
, then it doesn’t work with pooling. What happens is:
– The GameObject with the graph is instantiated
– The GameObject is disabled.
– The Graph is loaded
– The Graph starts running.
Is this a bug? Intuitively I would say that the graph would load asynchronously, but not run, because it’s been disabled before the graph has been completely loaded. Maybe I’m misunderstanding “First Activation” though.
Hey,
This is indeed close the order that things take place in that specific case (async loading + immediately disabling the gameobject). More specifically:
β The GameObject with the graph is instantiated.
– The Graph begins async loading (in Awake).
β The GameObject is disabled.
β The Graph async loading is completed.
β The Graph starts running (if “On Enable” is “Enable Behaviour”).
Within the Awake call of the GraphOwner, the graph is initialized and is loaded async. When the async load is finished, then the graph is started, by which point you have already disabled the gameobject. However, the graph is started only if the “On Enable” option on the inspector, is set to “Enable Behaviour”.
With that said, what I would suggest would be to change the “On Enable” option on the FSMOwner inspector to “Do Nothing”. As such, the graph will not automatically start, but you will instead need to call “owner.EnableBehaviour”, which can be done together when for example you enable the gameobject itself (using the pooled object).
Please let me know if that solution works for you, or if maybe we can try find another solution π
Thanks!
Join us on Discord: https://discord.gg/97q2Rjh
Hmm. It’s a problem in the sense that NodeCanvas has to be specially handled by the pooling code, for both retrieving from the pool and returning to the pool. Also a problem if I want to use one of these objects outside the pool.
> β The Graph async loading is completed.
Is there a spot in the code where this is confirmed? EG, “Okay, I just finished loading the graph, let me continue on…” I’d like to modify the code at this point to check and see if the owner is active in the hierachery before actually starting the graph. That way it works seamlessly under the hood, and pooling code doesn’t need to be aware of its particulars.
GraphOwner.cs, line 334:
Changing
if ( !isRunning && enableAction == EnableAction.EnableBehaviour ) {
To
if ( !isRunning && enableAction == EnableAction.EnableBehaviour && gameObject.activeInHierarchy ) {
Has the desired effect of not starting the graph if the GameObject is not active at the time the async load finishes. I can’t see any negative side-effects; pooling seems to work correctly as well as regular behavior.
Can you see any gotchas with this approach?
Hello again,
Yes, that is the point in code where “async-loading-is-done” is. Your code change is the first thing I thought about suggesting before and it does not really have any gotchas, but, it is also a change I can’t really make officially since some people may want (or expect) for the graph to start even if the gameobject is disabled (although this will hardly be the case). If you are going to do this change in your part though, I can’t foresee any issues with this change, if that works for you π
Join us on Discord: https://discord.gg/97q2Rjh
> […], it is also a change I canβt really make officially since some people may want (or expect) for the graph to start even if the gameobject is disabled
Fair enough! I think the documentation should be updated to reflect this behavior: it really does look kinda like a bug along the lines of “why is my graph running even though my GameObject is disabled?!” which is counter to how Unity works normally works.
I don’t suppose it’s possible to make this a configuration boolean if the user has selected Async
as their first activation?
Hey,
I could introduce an option for that (although truth is that I hate options for such things π ). I will also reconsider the possibility of adding the code change described above officially instead. It just needs a bit more thought π
Join us on Discord: https://discord.gg/97q2Rjh
I totally understand!
But I hope at least the behavior gets documented if its not going to change — I know now, but I think this will trip up other users.
Actually graph pooling is very difficult with sub graph.
I really want to have factory override for Graph. In my case I totally hacked NodeCanvas for subGraph pooling. NestedGraphNode just Load Graph by instancing it which is very not expected if I set graph to be async loaded.