Summary:
The schema validation logic in UStateTreeComponent::SetLinkedStateTreeOverrides and UStateTreeComponent::AddLinkedStateTreeOverrides is inverted compared to the documented intent in the comments. This causes the functions to reject StateTrees that have the correct UStateTreeComponentSchema, instead of accepting them.
Location:
The issue is present in the following functions in StateTreeComponent.cpp:
-
UStateTreeComponent::SetLinkedStateTreeOverrides
-
UStateTreeComponent::AddLinkedStateTreeOverrides
Problem Description:
The comments for these functions state: “The overrides won’t be set if they do not use the StateTreeComponentSchema schema.” This implies that only StateTrees with a schema that is or inherits from UStateTreeComponentSchema should be accepted.
However, the current implementation’s if condition is as follows:
StateTreeComponent.cpp
void UStateTreeComponent::SetLinkedStateTreeOverrides(FStateTreeReferenceOverrides Overrides)
{
// Validate the schema
for (const FStateTreeReferenceOverrideItem& Item : Overrides.GetOverrideItems())
{
if (const UStateTree* ItemStateTree = Item.GetStateTreeReference().GetStateTree())
{
if (ItemStateTree->GetSchema() == nullptr
|| ItemStateTree->GetSchema()->GetClass()->IsChildOf(UStateTreeComponentSchema::StaticClass()))
{
STATETREE_LOG(Warning, TEXT("%hs: Trying to set the linked overrides '%s' with a wrong schema. %s."),
__FUNCTION__,
*Item.GetStateTag().ToString(),
*ItemStateTree->GetFullName()
);
return;
}
}
}
LinkedStateTreeOverrides = MoveTemp(Overrides);
}
void UStateTreeComponent::AddLinkedStateTreeOverrides(const FGameplayTag StateTag, FStateTreeReference StateTreeReference)
{
// Validate the schema
if (const UStateTree* ItemStateTree = StateTreeReference.GetStateTree())
{
if (ItemStateTree->GetSchema() == nullptr
|| ItemStateTree->GetSchema()->GetClass()->IsChildOf(UStateTreeComponentSchema::StaticClass()))
{
STATETREE_LOG(Warning, TEXT("%hs: Trying to set the linked overrides with the wrong schema. %s."), __FUNCTION__, *ItemStateTree->GetFullName());
return;
}
}
LinkedStateTreeOverrides.AddOverride(FStateTreeReferenceOverrideItem(StateTag, MoveTemp(StateTreeReference)));
}
This condition evaluates to true and rejects the override if the schema is a child of UStateTreeComponentSchema, which is the exact opposite of the intended behavior described in the comment.
Impact:
Due to this bug, it is impossible to set overrides using StateTrees that are correctly configured with a UStateTreeComponentSchema, rendering these functions unusable as documented.
The logical condition should be inverted by negating the IsChildOf check. This will align the code’s behavior with the documentation.
// Suggested fix
if (ItemStateTree->GetSchema() == nullptr
|| !ItemStateTree->GetSchema()->GetClass()->IsChildOf(UStateTreeComponentSchema::StaticClass()))
{
// ...
}
This change will ensure that StateTrees with a schema that is not a UStateTreeComponentSchema (or a child class) are correctly rejected, as intended.
Thank you for your consideration.