NullReferenceException: Object reference not set to an instance of an object

tatoforever

New member
I get this error when using the Circle task from the Formation pack:
NullReferenceException: Object reference not set to an instance of an object BehaviorDesigner.Runtime.Formations.Tasks.FormationGroup.StartListeningForOrders (BehaviorDesigner.Runtime.Behavior agent) (at Assets/Behavior Designer Formations/Scripts/Tasks/FormationGroup.cs:157) BehaviorDesigner.Runtime.Behavior.SendEvent[T] (System.String name, T arg1) (at <8273d6b105784beab3b1f76a8d030c0c>:0) BehaviorDesigner.Runtime.Formations.Tasks.FormationGroup.OnUpdate () (at Assets/Behavior Designer Formations/Scripts/Tasks/FormationGroup.cs:375) BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <8273d6b105784beab3b1f76a8d030c0c>:0) BehaviorDesigner.Runtime.BehaviorManager.Tick (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree) (at <8273d6b105784beab3b1f76a8d030c0c>:0) BehaviorDesigner.Runtime.BehaviorManager.Tick () (at <8273d6b105784beab3b1f76a8d030c0c>:0) BehaviorDesigner.Runtime.BehaviorManager.Update () (at <8273d6b105784beab3b1f76a8d030c0c>:0)

Our BTs are external, they are used in a pool system and we populate the leader variables through code before calling EnableBehavior() on every BT instance. The variables seems to be well populated cause I can select the BT attached to my AI at runtime and see the variables references/values in the Variable list.
 
Last edited:
Hmm.. are you able to tell me how to reproduce that error based on the demo scene? It looks like the agents variable is null but that should be initialized with AddAgentToGroup. It looks like it has something to do with being a leader/not a leader so double check those values.
 
1065

Using an AgentManager, I instantiate the agent and I populate their first three variables you see in the image through code at runtime, before calling EnableBehavior(). I use a manger to make sure no one is trying to access data that isn't ready. Agents BT are enabled after their variables are assigned.

The way to repro it is, create an external behavior tree with the Circle task. Make sure you have an agent prefab with all the required components
Then using a MonoBehavior in your scene:
- instantiate the mono behavior trees, init them, assign them to the agent behavior component
- populate the leader, group and target transform variable to any valid value in your scene
- enable the behaviortree on the agents
And the error is shown in the Editor console

In the documentation it says AddAgentToGroup is for custom formation tasks. I'm not doing any custom groups or formations, just assigning the Leader and LeaderIndex through code.
 
Last edited:
I looked at the Formation demo scene but again it doesn't tell me anything. No idea what's causing the error.
Basically, what I'm doing is adding the Circle formation task and the group ID/leader is feed through code before behavior activation.
Ifound out that i don't even need to set the group ID, my AI only have one BT and they share the same group, zero.
In the code what seems to be null is the agents transfrom List. Looks like they are not properly setup by the FormationGroup. And something is telling me is not properly initialized because they are external behavior trees.
 
Last edited:
I just tried to reproduce this error with a external tree but wasn't able to. Here is my test case. Maybe this will help point to what is going wrong on your end?
 

Attachments

  • ExternalFormation.unitypackage
    5.3 KB · Views: 5
I'm going to take a look at your file but I'm having a similar problem with receiving events on the BT using the Has Received Event task:

Code:
NullReferenceException: Object reference not set to an instance of an object
BehaviorDesigner.Runtime.Tasks.HasReceivedEvent.OnEnd () (at Assets/Behavior Designer/Runtime/Tasks/Conditionals/HasReceivedEvent.cs:42)
BehaviorDesigner.Runtime.BehaviorManager.PopTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus& status, System.Boolean popChildren, System.Boolean notifyOnEmptyStack) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.PopTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus& status, System.Boolean popChildren) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.RunParentTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32& stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus status) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.RunParentTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32& stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus status) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.Tick (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.Tick () (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.Update () (at <8273d6b105784beab3b1f76a8d030c0c>:0)
The player makes damage to the AI, this damage is received on one of the AI components and then the event is sent to the AI behavior tree using the
Code:
BehaviorTree.SendEvent<object>("ReceiveDamage", enemyHealth == 0);

I tried subscribing after the BT is initialized both before and after calling EnableBehavior() on the BT and the result is the same, a null ref exception when the event is sent to the BT.
 
Last edited:
I made few changes to the test package you provided, made it a tiny pool system with and it works fine in the test scene. But in our game scene it doesn't work, I get nullreferences everytime. Though the setup is exactly the same.
I didn't had the chance to dig your source code but if you can provide some sort of hints that would help figuring out if your code is the culprit or I did something silly.
 
Both of those errors look related to variable initialization. It's tough to say what's going on without being able to reproduce it - can you modify my test scene to show those errors?
 
Ok,
I think I found the culprit, I was doing something weird with my pool system. It looks to be working now. I was able to transform your small example into a tiny pool system similar to the one in our game and it worked fine. I dig a bit more and found some weird references that shoudn't be in the pool (probably those are the one being nulled and referenced by the NavGroup system). I will double check and repost when Im 100% sure but it looks like it was my pool system.
 
I was able to reproduce the NullReferenceException bug on BT Events with your small example. It only happens when you are debugging an instance of any spawned agent with an attached Behavior Tree (at runtime) on Behavior Designer.
I attached the modified package. Here is how to repro the exception:
- Make sure Behavior Designer is visible (to debug runtime instances).
- Open the attached scene
- Hit play
- Wait for the agents to be active in the hierarchy and select any of them (or the first one at the top)
- Wait for the agents to reach destination (with Behavior Designer opened) at you will get a NullReferenceException when the BT tries to unregister from the event.
The event can be triggered at any time when you hit any key or mouse button, the console will display "ReceiveDamage: 25" on success

Please find the test package attached.
Here is the full error log:
NullReferenceException: Object reference not set to an instance of an object
BehaviorDesigner.Runtime.Tasks.HasReceivedEvent.OnBehaviorComplete () (at Assets/Behavior Designer/Runtime/Tasks/Conditionals/HasReceivedEvent.cs:98)
BehaviorDesigner.Runtime.BehaviorManager.DestroyBehavior (BehaviorDesigner.Runtime.Behavior behavior, BehaviorDesigner.Runtime.Tasks.TaskStatus executionStatus) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.DisableBehavior (BehaviorDesigner.Runtime.Behavior behavior, System.Boolean paused, BehaviorDesigner.Runtime.Tasks.TaskStatus executionStatus) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.PopTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus& status, System.Boolean popChildren, System.Boolean notifyOnEmptyStack) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.PopTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus& status, System.Boolean popChildren) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.Tick (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.Tick () (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.Update () (at <8273d6b105784beab3b1f76a8d030c0c>:0)
 

Attachments

  • TEST.unitypackage
    8.1 KB · Views: 6
Thanks for the repro scene. When you have the editor open the tree is destroyed at a different time so that's what is causing the null reference exception. If you add

Code:
            if (Owner == null) {
                return;
            }

That'll fix the exception. You'll also need to add this to FormationGroup.OnBehaviorComplete.
 
I added the null check to both FormationGroup and HasReceivedEvent OnBehaviorComplete method and it fixed the error. I guess you will push an update with this fix in your next version?
PS: I also had to add the null check at the OnStart and OnEnd method of HasReceivedEvent too (I was getting the nullref error here too).
Cheers,
 
Last edited:
Also,
Regarding the Tactical pack. In our game our enemies only have one target (the player) and SharedGameObjectList doesn't allow me to populate the list with BT Variables, only with references from the scene but our BTs are externals, so they can't reference anything directly from the scene, we populate those variables at runtime when the BT is instantiated.
I did the change already to TacticalGroup and it works fine. I added:
Code:
 public SharedGameObjectList targetGroup;
to the top and inside StartGroup() method I added:
Code:
                if (targetObject.Value) {
                    var damageable = (targetObject.Value.GetComponentInParent(typeof(IDamageable)) as IDamageable);
                    if (damageable != null) {
                        AddTarget(targetObject.Value.transform, damageable);
                    }
                } else if (targetGroup.Value.Count > 0) {//rest of if (leader.Value == null) statement

Is there any possibility for you to add these changes to the TacticalGroup class? Other people in our situation might benefit from this. Let me know if you want the modified file.
 
Last edited:
I'm having a new ref exception when using the Attack task of the Tactical pack:
NullReferenceException: Object reference not set to an instance of an object
BehaviorDesigner.Runtime.Tactical.Tasks.TacticalGroup.StartListeningForOrders (BehaviorDesigner.Runtime.Behavior agent) (at Assets/Behavior Designer Tactical/Scripts/TacticalGroup.cs:192)
BehaviorDesigner.Runtime.Behavior.SendEvent[T] (System.String name, T arg1) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.Tactical.Tasks.TacticalGroup.OnUpdate () (at Assets/Behavior Designer Tactical/Scripts/TacticalGroup.cs:297)
BehaviorDesigner.Runtime.Tactical.Tasks.Attack.OnUpdate () (at Assets/Behavior Designer Tactical/Scripts/Tasks/Attack.cs:16)
BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.Tick (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree) (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.Tick () (at <8273d6b105784beab3b1f76a8d030c0c>:0)
BehaviorDesigner.Runtime.BehaviorManager.Update () (at <8273d6b105784beab3b1f76a8d030c0c>:0)
Pointing to AddAgentToGroup(agent, agents.Count); inside the StartListeningForOrders(Behavior agent) method.
This error happens when the Attack task has a leader, if leader is null no error is shown.
 
Also,
Regarding the Tactical pack. In our game our enemies only have one target (the player) and SharedGameObjectList doesn't allow me to populate the list with BT Variables, only with references from the scene but our BTs are externals, so they can't reference anything directly from the scene, we populate those variables at runtime when the BT is instantiated.
I did the change already to TacticalGroup and it works fine. I added:
Code:
 public SharedGameObjectList targetGroup;
to the top and inside StartGroup() method I added:
Code:
                if (targetObject.Value) {
                    var damageable = (targetObject.Value.GetComponentInParent(typeof(IDamageable)) as IDamageable);
                    if (damageable != null) {
                        AddTarget(targetObject.Value.transform, damageable);
                    }
                } else if (targetGroup.Value.Count > 0) {//rest of if (leader.Value == null) statement

Is there any possibility for you to add these changes to the TacticalGroup class? Other people in our situation might benefit from this. Let me know if you want the modified file.

The restrictions should be the same between a SharedGameObjectList and a SharedGameObject. With targetGroup you can add the single GameObject to the list after you have instantiated the tree.

I'm having a new ref exception when using the Attack task of the Tactical pack:

Pointing to AddAgentToGroup(agent, agents.Count); inside the StartListeningForOrders(Behavior agent) method.
This error happens when the Attack task has a leader, if leader is null no error is shown.
Can tell me how to reproduce the error? The tactical demo scene has an example of using attack with a leader so you can base it off of that.
 
1118

Yeah but SharedGameObjectList is a "shared list" of GameObjects, I don't have that. I just have 1 target which is a SharedGameObject that is populated at runtime. HEnce why I added TargetObject to the base class. I don't need to create a list that contains only one gameObject for every enemy instance, we have lot of BT instances (25-30 instances). That's a little overkill to populate at runtime. This is a needed feature imho, not all games AI have multiple targets.

As for the new null error, I'll see if I can repro it.
 
Top