FEATURE REQUEST: Incorrect Schema Validation in UStateTreeComponent's Override Functions

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.

Hey!

I am pleased to announce that this has been addressed recently. Here is a link to the commit on our public GitHub: [StateTree] Fix schema test in StateTreeComponent.

-James