Broadcast Delegate using a State Tree Delegate Dispatcher in the parent does not work under certain conditions.

Hello.

Broadcast Delegate using a StateTree Delegate Dispatcher in the parent does not work under certain conditions.

I have attached a reproduction project and the reproduction method is as follows.

  1. Create states hierarchy in the state tree in the order of Root - A - B and set the Selection Behavior of state A to Try Enter.
  2. Create a StateTree Task Blueprint and use a timer node on the EnterState event to call a Broadcast Delegate using the StateTreeDelegateDispatcher of the task Blueprint member after n seconds.
  3. Add a Delay task to state A and set duration as 2 seconds, add the task created above and set duration as 6 seconds, and add transition to move to state B when On State Succeeded.
  4. Add a Delay task to the B state and set Run Forever to true, then add a transition to the Root state by specifying the Delegate Dispatcher in the task of state A as On Delegate.
  5. As a result of execution, it entered state A, entered state B 2 seconds later, and was expected to transition according to the delegate 4 seconds later, but the following log occurred: “LogStateTree: Error: Failed to broadcast the delegate. The instance probably stopped.”

I wonder if it is the engine’s intention for delegates to not work in this way, and if it’s appropriate to use them with below modification, since they work as expected.

StateTreeAsyncExecutionContext.cpp(112)

(Before)

`UE::StateTree::Async::FActivePathInfo ActivePath = GetActivePathInfo();
if (ActivePath.IsValid())
{
FStateTreeExecutionState& Exec = Storage->GetMutableExecutionState();
Exec.DelegateActiveListeners.BroadcastDelegate(Dispatcher, Exec);
if (UE::StateTree::ExecutionContext::MarkDelegateAsBroadcasted(Dispatcher, *ActivePath.Frame, *Storage))
{
ScheduleNextTick(Owner.Get(), StateTree.Get(), *Storage);
}

return true;
}`​

(​After)

`if (IsValidInstanceStorage())
{
FStateTreeExecutionState& Exec = Storage->GetMutableExecutionState();

int32 FrameIndex = Exec.IndexOfActiveFrame(FrameID);
if (FrameIndex != INDEX_NONE)
{
FStateTreeExecutionFrame* CurrentFrame = &Exec.ActiveFrames[FrameIndex];
if (CurrentFrame)
{
Exec.DelegateActiveListeners.BroadcastDelegate(Dispatcher, Exec);
if (UE::StateTree::ExecutionContext::MarkDelegateAsBroadcasted(Dispatcher, *CurrentFrame, *Storage))
{
ScheduleNextTick(Owner.Get(), StateTree.Get(), *Storage);

return true;
}
}
}
}`​

재현 방법

  1. Create states hierarchy in the state tree in the order of Root - A - B and set the Selection Behavior of state A to Try Enter.
  2. Create a StateTree Task Blueprint and use a timer node on the EnterState event to call a Broadcast Delegate using the StateTreeDelegateDispatcher of the task Blueprint member after n seconds.
  3. Add a Delay task to state A and set duration as 2 seconds, add the task created above and set duration as 6 seconds, and add transition to move to state B when On State Succeeded.
  4. Add a Delay task to the B state and set Run Forever to true, then add a transition to the Root state by specifying the Delegate Dispatcher in the task of state A as On Delegate.
  5. As a result of execution, it entered state A, entered state B 2 seconds later, and was expected to transition according to the delegate 4 seconds later, but the following log occurred: “LogStateTree: Error: Failed to broadcast the delegate. The instance probably stopped.”

Hello,

Was this working as you expected prior to 5.6? Which version of the engine was it working if so? We have been working on the instance data for StateTree as there have been some issues discovered recently. I am building the repro project now to look into it myself for what may be causing this, but it might be “by design” as changing states can reallocate memory for the StateTree so the initial binding is no longer valid.

-James

Hello, Thank you for reply.

State tree delegate was introduced in 5.6, but when using the existing state tree event, it works as expected in 5.5, but causes problems in 5.6. StateTreeAsyncExecutionContext was also introduced in 5.6 and this is where the related issues seem to be occurring.

In the repro project, it can reproduce it by simply changing the Broadcast Delegate to StateTree Send Event, the Transition condition of the state B to On Event, and specifying the same tag.