Stack Overflow Error on custom Task

MarkusKer

Member
Hello, i was trying to write some custom task to compare which enemy is the closest to the player but i am getting an stack overflow error.
Any Ideas?

using UnityEngine;
using BehaviorDesigner.Runtime;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace BehaviorDesigner.Runtime.Tasks.Unity.SharedVariables
{
[TaskCategory("Unity/SharedVariable")]
[TaskDescription("Returns success if the variable value is equal to the compareTo value.")]
public class CompareSharedFloatDistance : Conditional
{

public GameObject[] Swarm;
public float closest;
public List<float> myList = new List<float>();
public SharedFloat myIntVariable2;

public override TaskStatus OnUpdate()
{


Swarm = GameObject.FindGameObjectsWithTag("Enemy");
foreach (GameObject Climbing in Swarm)
{
if (Climbing.name == ("swarm"))
{
var test2 = Climbing.GetComponent<BehaviorTree>();
var myIntVariable1 = (SharedFloat)test2.GetVariable("Distance");

myList.Add(myIntVariable1.Value);

}
}

closest = myList.Min();



return myIntVariable2.Value.Equals(closest) ? TaskStatus.Success : TaskStatus.Failure;

}
}
}

Also i am wondering why the marked part of my behavior is only beeing executed once. How would i be able to check its value every now and then?
 

Attachments

  • test.PNG
    test.PNG
    44.7 KB · Views: 5
Even with the repeater above the selector it does not change the situation. once one of the child tasks is executing the formation, it does not try to repeat the sequences from the left again.
 

Attachments

  • 2.PNG
    2.PNG
    39.5 KB · Views: 3
what i am trying to do is , once the bool infront of the sequence is true the formation should be executed. however once the bool is false the sequence should stop and the selector should go on with the next sequence to the right.
 
i have rebuild my tree without my custom script. i am using 2 bool comparisons with repeaters. even now the bool has been changed during runtime, the selector is not choosing the correct sequence. However the already active sequence stays active even tho the bool at the front would be failed.
 

Attachments

  • 3.PNG
    3.PNG
    45.4 KB · Views: 4
I have taken a deeper look and it seems that i am getting the stack overflow error because of my behavior tree setup. I am only getting this error if there is more that one of this trees in use.
 

Attachments

  • 4.PNG
    4.PNG
    32.3 KB · Views: 3
I now completly understood the problematic but i am stil unable to solve it. the left wedge is the leader and the right wedge is the follower. i was able to run only one child task at a time using conditional aborts but as soon as both wedge tasks are anabled and the characters are active (one leader and one follower) i get the Stack overflow error. This is only happening with formations. If i use the seek task for example it works perfectly.
 

Attachments

  • 5.PNG
    5.PNG
    27.2 KB · Views: 7
Last edited:
Even with full stack tracing enabled, it does not show the origin of the error. Even with just conditional aborts in use the error is happening. It can be replicated quiet easily, having 2 AI characters with the same behavior attached. in the behavior there is an conditional abort checking if an bool is true or not andthan deciding if it is an leader or not. At the exact moment the following agent is at the point of using the wedge task the error happens.
 

Attachments

  • 6.PNG
    6.PNG
    13 KB · Views: 5
Hello, i was trying to write some custom task to compare which enemy is the closest to the player but i am getting an stack overflow error.
Any Ideas?

using UnityEngine;
using BehaviorDesigner.Runtime;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace BehaviorDesigner.Runtime.Tasks.Unity.SharedVariables
{
[TaskCategory("Unity/SharedVariable")]
[TaskDescription("Returns success if the variable value is equal to the compareTo value.")]
public class CompareSharedFloatDistance : Conditional
{

public GameObject[] Swarm;
public float closest;
public List<float> myList = new List<float>();
public SharedFloat myIntVariable2;

public override TaskStatus OnUpdate()
{


Swarm = GameObject.FindGameObjectsWithTag("Enemy");
foreach (GameObject Climbing in Swarm)
{
if (Climbing.name == ("swarm"))
{
var test2 = Climbing.GetComponent<BehaviorTree>();
var myIntVariable1 = (SharedFloat)test2.GetVariable("Distance");

myList.Add(myIntVariable1.Value);

}
}

closest = myList.Min();



return myIntVariable2.Value.Equals(closest) ? TaskStatus.Success : TaskStatus.Failure;

}
}
}

Also i am wondering why the marked part of my behavior is only beeing executed once. How would i be able to check its value every now and then?

You need to run myList.Clear() before or after execution, otherwise it grows infinitely. Also, this code it very unoptimized, you shouldn't use GetComponent() on update etc. Actually, to find the closest element you don't need this list at all:


C#:
            float closest = float.PositiveInfinity;

            foreach (GameObject climbing in GameObject.FindGameObjectsWithTag("Enemy"))
            {
                if (climbing.name == "swarm")
                {
                    float distance = ((SharedFloat)climbing.GetComponent<BehaviorTree>().GetVariable("Distance")).Value;
                    if (distance < closest)
                    {
                        closest = distance;
                    }
                }
            }

But this is only for tests, this method is way too slow and garbage-heavy.
 
Last edited:
You need to run myList.Clear() before or after execution, otherwise it grows infinitely. Also, this code it very unoptimized, you shouldn't use GetComponent() on update etc. Actually, to find the closest element you don't need this list at all:


C#:
            float closest = float.PositiveInfinity;

            foreach (GameObject climbing in GameObject.FindGameObjectsWithTag("Enemy"))
            {
                if (climbing.name == "swarm")
                {
                    float distance = ((SharedFloat)climbing.GetComponent<BehaviorTree>().GetVariable("Distance")).Value;
                    if (distance < closest)
                    {
                        closest = distance;
                    }
                }
            }

But this is only for tests, this method is way too slow and garbage-heavy.
Thank you so much i will test it. But this is not solving my behavior tree "Formations"problem.
 
You should use a Self/Both conditional abort in order to start/stop the formations task.
 
Top