SendEvent doesn't work when called in Start() method of MonoBehavior

lukeiy

New member
I have an event which I want to send to the tree on start:
Code:
    private void Start()
    {
        if (InitialDestination.HasValue)
        {
            Debug.Log($"sending destination {InitialDestination.Value}");
            _behaviorTree.SendEvent<object>("RecievedDestination", InitialDestination.Value);
            InitialDestination = null;
        }
    }

If I put this code into Start, the tree does not receive the event (I checked with a Log task). I have to put it into Update instead before the event works.

1671433074639.png
 
Last edited:
My guess is that the Has Received Event task hasn't started yet so that's why the event hasn't been received. You could tick the behavior tree manually and ensure it is ticked at least once before the start method is called.
 
This is a bug no? The common behavior in the unity framework expects components to be ready to go at Start, initialization should be completed by the end of Awake.
 
Without seeing your entire tree I am not able to completely say but I don't think it is. My guess is that you are sending the event before Has Received Event has a chance to even register for the event so that's why it's not being received. If you ensure the tree is enabled and ticked before you send the event it'll work.
 
Without seeing your entire tree I am not able to completely say but I don't think it is. My guess is that you are sending the event before Has Received Event has a chance to even register for the event so that's why it's not being received. If you ensure the tree is enabled and ticked before you send the event it'll work.
What happens is a prefab containing a Behavior Tree component is instantiated, and that prefabs Start() method sends an event to the Behavior Tree. Do nodes on the tree all get initialized (including event registering) in Awake() ? I'm not sure how else the tree wouldn't be ready to recieve events in Start()
 
It could be an execution order issue - the nodes get initialized within start as well.
 
Here's a test case which doesn't work for me, is there something I'm missing then?

Set up a tree watching an event called "Testing"

1671631569253.png

With a script:

Code:
using BehaviorDesigner.Runtime;
using UnityEngine;

public class test : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        var bt = GetComponent<BehaviorTree>();
        bt.SendEvent("Testing");
    }
}
 
Your behavior tree is ending right away because Has Received Event returns a status of failure. You should keep Has Received Event active with conditional aborts.

Beyond that it depends on the execution order. The behavior tree has to start before your test script otherwise the event won't be captured.
 
Your behavior tree is ending right away because Has Received Event returns a status of failure. You should keep Has Received Event active with conditional aborts.

Beyond that it depends on the execution order. The behavior tree has to start before your test script otherwise the event won't be captured.
Ah I forgot to add that the tree is set to 'Restart when complete' and does not reset values on restart, but just to check I used this tree and observed the same behavior:
1671674791543.png

My point was that, shouldn't the initialization of the tree happen in Awake(), not Start(), because then race conditions like this can be avoided. Like other Unity components, the tree should be ready to go (including ready to receive events) by the time the Start() stage of the lifecycle is hit.

"Instead, you should use Awake to set up references between scripts, and use Start, which is called after all Awake calls are finished, to pass any information back and forth."
 
If you download the runtime source from the downloads page you can easily change when the tree is initialized within the BehaviorTree class. I can also look at adding this as an option.
 
Top