I ran into an issue where some StateTrees fail to initialize properly and require re-compilation every single time the editor is run. These StateTree assets also fail to build for packaged builds. These are the only error messages that are printed when the StateTrees fail initialization:
LogStateTree: Warning: StateTree /Game/AI/StateTree_AI/ST_DefaultNPC.ST_DefaultNPC: could not compile. Please resave the StateTree asset.
LogStateTree: Warning: AIC_DefaultNPC_C_0: FStateTreeExecutionContext::FStateTreeExecutionContext: StateTree asset is not valid ('AIC_DefaultNPC_C_0' using StateTree 'StateTree /Game/AI/StateTree_AI/ST_DefaultNPC.ST_DefaultNPC')
There are no compile errors whatsoever in these StateTrees. In order to work around being required to re-compile multiple StateTrees every editor run, I simple overload the StateTreeAIComponent and re-compile it in code:
void UBFStateTreeAIComponent::InitializeComponent()
{
Super::InitializeComponent();
if (StateTreeRef.IsValid())
{
UStateTree* stateTree = const_cast<UStateTree*>(StateTreeRef.GetStateTree());
stateTree->LastCompiledEditorDataHash = 0xFAFAFAFA;
stateTree->CompileIfChanged();
return;
}
}
This obviously will not work in packaged builds because StateTree compilation is entirely within the editor.
This bug does not appear to be related to the complexity of the StateTree as I have reproduced this with an extremely simple StateTree that has no custom tasks, parameters, evaluators, conditions, etc.
Looking into this a little more, the error messages show that this appears to be an engine/editor initialization order issue. The only place where the string “could not compile. Please resave the StateTree asset” could be printed is if the StateTree compilation delegates are not bound:
void UStateTree::CompileIfChanged()
{
if (UE::StateTree::Delegates::OnRequestCompile.IsBound() && UE::StateTree::Delegates::OnRequestEditorHash.IsBound())
{
... [SNIP] ...
}
else
{
ResetCompiled();
UE_LOG(LogStateTree, Warning, TEXT("%s: could not compile. Please resave the StateTree asset."), *GetFullName());
}
}
One interesting observation is that if the failing StateTrees are not bound to any AI Controllers and their StateTree editor window is open, then the editor log will show them as successfully compiling when you load a map and those editor windows open.
Note that this does not appear to be a new issue as it was brought up in April 2022 as well - StateTree requires compile in order to run on editor start
If anyone has any ideas around this I would greatly appreciate this as it blocks being able to test in packaged builds. The next thing I’m going to try is runtime binding of StateTrees to StateTreeAIComponents to work around the potential initialization order issue noted above.