When a Linked Asset state (StateA) in a MainTree links to a SubTree with overridden parameters, the parameter overrides are correctly applied on the first entry. However, if the SubTree completes (Tree Succeeded) and there is no completion transition defined on StateA, the engine falls back to Root and re-selects StateA in the same frame. On this re-entry, the parameter overrides are not applied — the SubTree receives default parameter values instead.
This issue exists in UE 5.7 (our base) and is still present in UE 5.8 preview.
Root Cause
In FStateTreeExecutionContext::SelectStateInternal (StateTreeExecutionContext.cpp), during the “Update state parameters” section:
// Instantiate temporary state parameters if not done yet.
FStateTreeDataView NextStateParametersView = GetDataViewOrTemporary(NextParentFrame, *NextFrame, NextState.ParameterDataHandle);
if (!NextStateParametersView.IsValid())
{
// ... create temporary instance with override values ...
}
GetDataViewOrTemporary calls IsHandleSourceValid, which checks IsActiveInstanceHandleSourceValid. On re-entry within the same frame, the old state has not yet been removed from ActiveStates, and its instance data in storage is still valid. Therefore IsHandleSourceValid returns true, and GetDataViewOrTemporary returns the stale old data view. Because NextStateParametersView is valid, the temporary instance creation (which would apply the parameter override) is skipped entirely.Later in UpdateInstanceData, the state is correctly identified as non-common (new state due to CompletedTransitionStatesCreateNewStates
in default StateSelectionRules). It looks for temporary instance data via FindInstanceTempData
— but finds none (because it was never created). It then falls back to the SubTree’s GetDefaultParameters(), losing the override values.
Our Fix
We guard the GetDataViewOrTemporary call with bShouldCreateNewState. When the state is being recreated, we skip the lookup to ensure the temporary instance is always created with the correct override values:
// When creating a new state, skip GetDataViewOrTemporary which may return stale data from the
// still-active old instance, causing the temporary creation below to be skipped. Without a
// temporary, UpdateInstanceData falls back to the SubTree's default parameters.
FStateTreeDataView NextStateParametersView;
if (!bShouldCreateNewState)
{
NextStateParametersView = GetDataViewOrTemporary(NextParentFrame, *NextFrame, NextState.ParameterDataHandle);
}
if (!NextStateParametersView.IsValid())
{
// ... existing temporary creation logic (unchanged) ...
}