NodeCanvas Forums › Support › Serialization not taking place in runtime
A brief overview of what I wrote on discord channel.
I was trying to separate AI into three parts:
– the target selection
– the target seeking and
– the attack behaviour
to allow reusability.
I used the following code to create a new Behaviour Tree by mixing trees of each one of the previous states.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public static BehaviourTree Assemble(string name, Blackboard blackboard, params BehaviourTree[] trees) { var behaviourTree = ScriptableObject.CreateInstance<BehaviourTree>(); behaviourTree.name = string.Format("{0} behaviour", name); var sequencer = behaviourTree.AddNode<Sequencer>(); behaviourTree.primeNode = sequencer; foreach (var tree in trees) { if (tree == null) continue; var subTree = sequencer.AddChild<SubTree>(); subTree.subTree = Object.Instantiate(tree); subTree.subTree.GetDefinedParameters().ForEach(x => x.bb = blackboard); } return behaviourTree; } |
The behaviours work well for behaviour tree owners that exist in the scene upon starting the game, but when I’m trying to instantiate gameobjects from prefabs during runtime, I get behaviour trees with no nodes in them.
I traced the problem into the GetInstance method. It tries to instantiate the a graph that I created by code, resulting in a graph that has no nodes in it. The method responsible for cloning is as follows (Graph.cs@199)
1 2 3 4 5 6 7 |
public static T Clone<T>(T graph) where T:Graph{ var newGraph = (T)Instantiate(graph); newGraph.name = newGraph.name.Replace("(Clone)", ""); return (T)newGraph; } |
We are continuing here after admin’s decision 😛
Hey,
Thanks for posting the issue here as well.
I just want to let you know that I am still looking at this. Serialization is restricted in the editor only for performance reasons. I am still looking at a proper way for what you are doing here, to work, but also retain the perofmance gained from limiting the serialization in editor only. I will let you know as soon as I have some solution/answer (hopefully within this week days).
Thank you!
Join us on Discord: https://discord.gg/97q2Rjh
Hello!
I’m also running into a similar issue, has there been any development on it?
At runtime I’m able to instantiate agents from prefabs and assign Behaviour Trees that I created in the editor with no issue. If I try to generate a Behaviour Tree at runtime and assign it to my instantiated agent, the agent’s Behaviour Tree is empty. However, if I cache the generated Behaviour Tree elsewhere and inspect it, it has all of the nodes.
I can provide additional information if needed but OP outlined the issue I’m seeing pretty well.
Hello,
What version of NodeCanvas are you using please? Serialization is possible in runtime for sometime now and the restriction has been removed (it was basically just a game running check in the graph code SelfSerialize method which was removed).
Can you please provide more information, because it might be something else.
Thank you!
Join us on Discord: https://discord.gg/97q2Rjh
Hey,
I’m using version 3.2.1 with Unity version 2021.3.1f1
Additional information:
My goal is to generate behavior trees programmatically at runtime and assign them to the BehaviourTreeOwner component of an agent prefab as it’s instantiated. The issue is that when I attempt to assign a tree created at runtime to one of my agents, the tree is empty and I receive no warnings/errors. Behaviour trees created in Edit Mode can be assigned with no issue, I only receive issues when creating the tree at runtime.
Since my first post I have setup my scripts to run in Edit Mode. This enables me to programmatically create the trees in Edit Mode and load them into the agents in Play Mode without any issue. However, it is still preferable to handle this at runtime if possible.
The setup:
The agent prefab has Blackboard and BehaviourTreeOwner components attached. I use an AgentProfile class to store the desired behavior tree and assign it to the agent when they spawn.
My logic for creating the trees is nearly identical to the ‘Creating a Behaviour in Code’ guide from the documentation.
Let me know if you need any additional information.
Thanks!
Hello and sorry for the late reply!
Indeed, in version 3.2.1, serialization in runtime was still disabled, however you can simple enable it by opening up Graph.cs and change line #67 to be like this, essentially commenting out or deleting the check for runtime:
1 2 3 4 5 |
if ( haltForUndo /*|| Threader.applicationIsPlaying || Application.isPlaying*/ ) { return false; } |
(Please note that a similar check is also done in Blackboard.cs at line #43 in case you also want to change that).
Please let me know if making the above modification works for you.
Thanks!
Join us on Discord: https://discord.gg/97q2Rjh