Summary:
This appears to be a crash in StateTree Helpers’ DispatchPostEditToNodes which occurs whenever the user attempts to modify a nested array property in StateTree, such as an array contained inside a struct. If a programmer manually bypasses the offending check (check(CurrentPropNode->GetNextNode() == nullptr)), then the observed behavior is that the array elements display does not update until the parent property is toggled closed and open again, after which everything will appear and behave normally. Therefore, the underlying property appears to be correctly updated, indicating that the offending code handles visual updates only.
We have reproduced this with array properties of both regular object pointers as well as instanced objects.
This began occurring when we upgrade to engine version 5.6.
Users who do not have the programmer superpower of bypassing the offending check will simply have their editor crash.
Repro:
- Create a simple State Tree Property Function that uses at least one array property. (see sample below)
- In any State Tree, add a task that uses an array property matching the type of the Property Function you just created.
- Bind that task’s array property to the Property Function you created.
- In the Property Function’s array, attempt to add or remove an element.
- Observe the editor crash.
Sample Property Filter:
USTRUCT()
struct MYPROJECT_API FMyFilterPropertyFunctionInstanceData
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, Category = "Input")
TArray<AActor*> Actors;
UPROPERTY(EditAnywhere, Instanced, Category = "Parameter")
TArray<TObjectPtr<UMyProjectConditional>> Conditionals;
UPROPERTY(VisibleAnywhere, Category = "Output")
TArray<AActor*> MatchingActors;
};
USTRUCT(meta=(DisplayName = "Actors Matching Filter"))
struct MYPROJECT_API FMyFilterPropertyFunction : public FStateTreePropertyFunctionBase
{
GENERATED_BODY()
using FInstanceDataType = FMyFilterPropertyFunctionInstanceData;
virtual const UStruct* GetInstanceDataType() const override { return FInstanceDataType::StaticStruct(); }
virtual void Execute(FStateTreeExecutionContext& Context) const override;
};
Steps to Reproduce
Repro:
- Create a simple State Tree Property Function that uses at least one array property.
- In any State Tree, add a task that uses an array property matching the type of the Property Function you just created.
- Bind that task’s array property to the Property Function you created.
- In the Property Function’s array, attempt to add or remove an element.
- Observe the editor crash.
Sample Property Filter:
USTRUCT()
struct MYPROJECT_API FMyFilterPropertyFunctionInstanceData
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, Category = "Input")
TArray<AActor*> Actors;
UPROPERTY(EditAnywhere, Instanced, Category = "Parameter")
TArray<TObjectPtr<UMyProjectConditional>> Conditionals;
UPROPERTY(VisibleAnywhere, Category = "Output")
TArray<AActor*> MatchingActors;
};
USTRUCT(meta=(DisplayName = "Actors Matching Filter"))
struct MYPROJECT_API FMyFilterPropertyFunction : public FStateTreePropertyFunctionBase
{
GENERATED_BODY()
using FInstanceDataType = FMyFilterPropertyFunctionInstanceData;
virtual const UStruct* GetInstanceDataType() const override { return FInstanceDataType::StaticStruct(); }
virtual void Execute(FStateTreeExecutionContext& Context) const override;
};
We certainly do not want this crashing the editor. I can say it does not happen in our latest version, but that is because there is not an option to bind to instance data properties of the property function with an output array. Which is unfortunately not very helpful, and I feel may be a use case we just had not encountered internally so it has not been addressed. I am reaching back to our dev who has been working on property functions and property bindings in StateTree about this to see if there is more work coming or other means to set this data.
-James
I have spoken with the team and it is a regression we had not caught. The idea is that you should be able to bind to things from the property function and that adding/binding to individual elements of an array should work without crashing. You cannot however bind the array to a parameter AND add individual elements in the editor. I think the missing view for bindings in 5.7 is due to how the UI gets updated to prevent binding to individual elements. I don’t have an ETA, but with it being a regression I imagine the turnaround will be fairly quick as those are treated with higher priority.
Thank you! This use case is, unfortunately, a very common and necessary one for us.
Is there an issue we can watch to see when a fix comes through for this?
The good news is that I have something better than a issue tracker link. This has been addressed and is in UE5 Main P4 at CL#47885758. I believe it will not be in a release stream until 5.8, but you can cherrypick it now. If you need the GitHub commit link instead, let me know and I can track that down.
-James