Convert 2+ AI Agents from Solo to Teammate

Hello! I currently have 2 AI agents that work independently and I'd like to put them on the same team. I've placed them on the same layer and switched both of their External Behavior trees from "Solo" to "Team" but I'm getting the following:
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at <695d1cc93cca45069c528c15c9fdd749>:0) System.ThrowHelper.ThrowArgumentOutOfRangeException () (at <695d1cc93cca45069c528c15c9fdd749>:0) Opsive.DeathmatchAIKit.TeamManager.SetLeaderInternal (UnityEngine.GameObject player, System.Boolean start) (at Assets/Opsive/DeathmatchAIKit/Scripts/Game/TeamManager.cs:209) Opsive.DeathmatchAIKit.TeamManager.SetLeader (UnityEngine.GameObject player, System.Boolean start) (at Assets/Opsive/DeathmatchAIKit/Scripts/Game/TeamManager.cs:175) Opsive.DeathmatchAIKit.AI.Actions.SearchForTarget.OnEnd () (at Assets/Opsive/DeathmatchAIKit/Scripts/AI/Actions/Attack/SearchForTarget.cs:153) 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 <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.DestroyBehavior (BehaviorDesigner.Runtime.Behavior behavior, BehaviorDesigner.Runtime.Tasks.TaskStatus executionStatus) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.DisableBehavior (BehaviorDesigner.Runtime.Behavior behavior, System.Boolean paused, BehaviorDesigner.Runtime.Tasks.TaskStatus executionStatus) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.DisableBehavior (BehaviorDesigner.Runtime.Behavior behavior, System.Boolean paused) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.DisableBehavior (BehaviorDesigner.Runtime.Behavior behavior) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.OnApplicationQuit () (at <3ed82e893f584901a16bc2e097c74b57>:0)
Is it necessary to "hard code" the target on the Behavior Tree component?

My real question: What is the fastest way to convert these agents from solo players to teammates?

Thanks!!
 
What is line 209 of the TeamManager? For me it is a }. It looks like that is occurring when you end the game so does it work before that?
 
I ran it again and below is the first error that appears while the game is running:
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at <695d1cc93cca45069c528c15c9fdd749>:0) System.ThrowHelper.ThrowArgumentOutOfRangeException () (at <695d1cc93cca45069c528c15c9fdd749>:0) Opsive.DeathmatchAIKit.TeamManager.GetLeaderInternal (UnityEngine.GameObject player) (at Assets/Opsive/DeathmatchAIKit/Scripts/Game/TeamManager.cs:165) Opsive.DeathmatchAIKit.TeamManager.GetLeader (UnityEngine.GameObject player) (at Assets/Opsive/DeathmatchAIKit/Scripts/Game/TeamManager.cs:143) Opsive.DeathmatchAIKit.AI.Conditions.ShouldLeadSearch.OnUpdate () (at Assets/Opsive/DeathmatchAIKit/Scripts/AI/Conditions/Team/ShouldLeadSearch.cs:41) BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunParentTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32& stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus status) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunParentTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32& stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus status) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunParentTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32& stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus status) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunParentTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32& stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus status) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunParentTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32& stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus status) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunParentTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32& stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus status) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.RunTask (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree, System.Int32 taskIndex, System.Int32 stackIndex, BehaviorDesigner.Runtime.Tasks.TaskStatus previousStatus) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.Tick (BehaviorDesigner.Runtime.BehaviorManager+BehaviorTree behaviorTree) (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.Tick () (at <3ed82e893f584901a16bc2e097c74b57>:0) BehaviorDesigner.Runtime.BehaviorManager.Update () (at <3ed82e893f584901a16bc2e097c74b57>:0)
 
What is line 165 for you? For me it is a return statement which will never return null.
 
Perhaps the better question to ask is:
If I have 2 working AI agents using the "Solo" External Behavior, what is needed to get them on the same team?
 
return closestLeader;
That's the same for me. There is no array on that line so I'm not sure how it is saying the index is out of range.

Perhaps the better question to ask is:
If I have 2 working AI agents using the "Solo" External Behavior, what is needed to get them on the same team?
You should be able to switch the behavior tree like you are doing. The error that you are receiving doesn't match the exception that is being thrown.
 
I set the External Behavior back to Solo and everything worked fine. I then switched it to Team and got the same error message. Digging deeper I found that teamIndex = -1 which is what's blowing up m_FormationGroups[teamIndex].Count

I'm continuing to dig, but any idea what might be causing this?
 
Ah, that gives me a clue. On the Deathmatch Agent did you select Add To Team? Also, make sure you add the TeamManager singleton to your scene. Hopefully that'll fix everything.
 
The TeamManager object was being created at runtime so I did not create one separately. Per your post, I've copied it from runtime and pasted into the scene so that it's always present. For the AI agent I selected "Add To Team" and entered "10" for the "Team Index" but I'm now getting this error:

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at <695d1cc93cca45069c528c15c9fdd749>:0) System.ThrowHelper.ThrowArgumentOutOfRangeException () (at <695d1cc93cca45069c528c15c9fdd749>:0) Opsive.DeathmatchAIKit.TeamManager.AddTeamMemberInternal (UnityEngine.GameObject player, System.Int32 teamIndex) (at Assets/Opsive/DeathmatchAIKit/Scripts/Game/TeamManager.cs:112) Opsive.DeathmatchAIKit.TeamManager.AddTeamMember (UnityEngine.GameObject player, System.Int32 teamIndex) (at Assets/Opsive/DeathmatchAIKit/Scripts/Game/TeamManager.cs:86) Opsive.DeathmatchAIKit.AI.DeathmatchAgent.Start () (at Assets/Opsive/DeathmatchAIKit/Scripts/AI/DeathmatchAgent.cs:244)
 
Line 112 for me in TeamManager is a } so it can't be throwing an exception. My guess is that your formatting is different. A team index of 10 is high - you should do it as 0, 1, 2, etc. I would insert a breakpoint in the AddTeamMemberInternal method and backtrack why it is throwing the exception.
 
So I've managed to resolve the remaining console errors. The final errors were a result of the Team Index - I was treating it as an ID as opposed to an array index, my mistake! Now no errors are thrown but the agents are attacking each other. Both have "Add To Team" enabled and both have a Team Index value of 0. What else could I be missing?
 
I also tried setting the Teammates size to 1 for each of the agents, and listing the other agent as "Element 0" (for each of the agents). But they still attacked one another. Is this a necessary step, or am I on the wrong track?
 
@Justin I am wondering if something is corrupt behind the scenes. I am still unable to prevent the agents from acting as teammates, and I noticed that whenever I deselect/reselect an agent in the Hierarchy View, its waypoints are set back to 0.
 
Now no errors are thrown but the agents are attacking each other. Both have "Add To Team" enabled and both have a Team Index value of 0. What else could I be missing?

The agents attack based on the layers specified in the Character Layer Manager. You can debug what layers are being used by setting a breakpoint within the IsTargetInSight method of DeathmatchAgent.

@Justin I am wondering if something is corrupt behind the scenes. I am still unable to prevent the agents from acting as teammates, and I noticed that whenever I deselect/reselect an agent in the Hierarchy View, its waypoints are set back to 0.
This sounds like it is related to this:


With the Deathmatch AI Kit the waypoints are set at runtime with the Object Identifier by the Deathmatch Manager (Waypoint Parent ID).
 
@Justin Thank you for clarifying the agents' logic in terms of determining enemies to attack. You were correct - while the root agent object had the right layer, the collider beneath it was set to the wrong layer which is why the agents were attacking one another.

In terms of the waypoints disappearing, I think this may be a bug. I am not using the Deathmatch Manager and if you select an agent at runtime the correct waypoints are shown. It seems to be an issue with refreshing that array in the inspector.

VERY MUCH appreciate the help!!
 
In terms of the waypoints disappearing, I think this may be a bug. I am not using the Deathmatch Manager and if you select an agent at runtime the correct waypoints are shown. It seems to be an issue with refreshing that array in the inspector.
How are you setting the waypoints?
 
By selecting the agent in the Hierarchy, setting the Waypoints size in the Behavior Tree component, and dragging in waypoints from the Hierarchy to the Element slots
 
This does sound related to this:


Since you are working with prefabs/external trees you will need to load the waypoints at runtime similar to the Deathmatch AI Kit.
 
Top