We have a script that sets the Graph of a BehaviorGraphAgent at runtime and then enables it.
When doing that, I am getting an error in one of my custom nodes. I couldn’t figure out why it was happening - is this a bug with my code? ![]()
Here is the (simplified) script that sets the graph and enables it. We don’t enable it by default for the purpose of multiplayer (only the host does it).
public BehaviorGraphAgent BehaviorGraphAgent;
void Start() {
BehaviorGraphAgent.Graph = m_CreatureDefinition.BehaviorGraph;
BehaviorGraphAgent.enabled = true;
}
Here is the error stacktrace:
NullReferenceException: Object reference not set to an instance of an object
SetVectorToRandomDungeonTileAction.OnStart () (at Assets/Scripts/Behaviour/Actions/SetVectorToRandomDungeonTileAction.cs:16)
Unity.Behavior.Node.Start () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:101)
Unity.Behavior.BehaviorGraphModule.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/BehaviorGraphModule.cs:117)
Unity.Behavior.Node.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:168)
Unity.Behavior.SequenceComposite.OnStart () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Nodes/Composites/SequenceComposite.cs:27)
Unity.Behavior.Node.Start () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:101)
Unity.Behavior.BehaviorGraphModule.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/BehaviorGraphModule.cs:117)
Unity.Behavior.Node.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:168)
Unity.Behavior.BranchingConditionComposite.OnStart () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Nodes/Composites/BranchingConditionComposite.cs:61)
Unity.Behavior.Node.Start () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:101)
Unity.Behavior.BehaviorGraphModule.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/BehaviorGraphModule.cs:117)
Unity.Behavior.Node.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:168)
Unity.Behavior.SwitchComposite.OnStart () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Nodes/Composites/SwitchComposite.cs:48)
Unity.Behavior.Node.Start () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:101)
Unity.Behavior.BehaviorGraphModule.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/BehaviorGraphModule.cs:117)
Unity.Behavior.Node.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:168)
Unity.Behavior.RestartModifier.OnStart () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Nodes/Decorators/Aborts/RestartModifier.cs:41)
Unity.Behavior.Node.Start () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:101)
Unity.Behavior.BehaviorGraphModule.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/BehaviorGraphModule.cs:117)
Unity.Behavior.Node.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:168)
Unity.Behavior.RepeaterModifier.OnStart () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Nodes/Decorators/RepeaterModifier.cs:30)
Unity.Behavior.Node.Start () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:101)
Unity.Behavior.BehaviorGraphModule.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/BehaviorGraphModule.cs:117)
Unity.Behavior.Node.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:168)
Unity.Behavior.ParallelAllComposite.OnStart () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Nodes/Composites/ParallelAllComposite.cs:25)
Unity.Behavior.Node.Start () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:101)
Unity.Behavior.BehaviorGraphModule.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/BehaviorGraphModule.cs:117)
Unity.Behavior.Node.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:168)
Unity.Behavior.Start.OnStart () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Nodes/Decorators/Start.cs:31)
Unity.Behavior.Node.Start () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Node.cs:101)
Unity.Behavior.BehaviorGraphModule.StartNode (Unity.Behavior.Node node) (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/BehaviorGraphModule.cs:117)
Unity.Behavior.BehaviorGraph.Start () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/BehaviorGraph.cs:51)
Unity.Behavior.BehaviorGraphAgent.Start () (at ./Library/PackageCache/com.unity.behavior/Runtime/Execution/Components/BehaviorGraphAgent.cs:428)
And here is the custom node script. Line number 16 is the error. Agent.Value is null. CreatureController is definitely on the same GameObject as the BehaviorAgent component. Note that when setting the graph manually in the editor inspector ahead of time it doesn’t error, it only happens when I set it via script at runtime.
using System;
using Unity.Behavior;
using UnityEngine;
using Action = Unity.Behavior.Action;
using Unity.Properties;
[Serializable, GeneratePropertyBag]
[NodeDescription(name: "Set Vector to random dungeon tile", story: "Set [Vector] to random dungeon tile for [Agent]", category: "Action/Dungeon", id: "bc61c7654dfb5df775d6db48e5334192")]
public partial class SetVectorToRandomDungeonTileAction : Action {
[SerializeReference] public BlackboardVariable<Vector3> Vector;
[SerializeReference] public BlackboardVariable<CreatureController> Agent;
protected override Status OnStart() {
// It's better to fail gracefully and sleep at their current position
if (Vector.Value == null || Agent.Value == null || Agent.Value.Dungeon == null) {
Vector.Value = Agent.Value.transform.position;
return Status.Success;
}
Vector.Value = Agent.Value.Dungeon.GetRandomTile().Placement.Bounds.center;
return Status.Success;
}
}