I am integrating some of our studio changes into the 5.6 engine upgrade, including various incomplete coverages of handling of struct references. I noticed that a lot of the property binding stuff was moved into a new module. In 5.5.3, I had fixed some issues related to struct reference binding and context variables, as well as added some code for FInstancedStruct based binding.
Looking at 5.6 with fresh eyes against state tree bindings I have from prior, I wanted to give a fresh look at the holes in functionality that remain.
There is some incomplete handling of FStateTreeStructRef
- The if (SourceProperty == nullptr) block has no handling of StructReferenceType, so struct reference types are unsupported in the circumstance where SourceProperty is null. This is true for situations where you are binding to context variables via a struct reference.
- UStateTreeComponentSchema::CollectExternalData doesn’t find components that live on the Pawn, only the controller. Related, I think it would be preferable to use UE_CVLOG_UELOG, rather than just UE_CVLOG. You see Failed to collect external data … in the normal log, but you have no idea what didn’t resolve without looking in the visual logger.
In the handling of the StructReferenceType block, the comment and conditional suggest that StructReferenceType->StructReferenceType will fall through and be resolved with some normal proerty copy? Do I understand that right? Should that not be resolved to a EPropertyCopyType::CopyStruct if the structs are equal? I don’t see handling further down that would do that.
Fix to #1
[Image Removed]
Bug #2 - Unrelated to property binding, I am trying to understand the changes to the state tree schema. I appreciate that the SetContextData function is now virtual on the schema, to allow you to subclass and feed in additional context data. I did notice that my state tree was failing to resolve all external data, and noticed that UStateTreeComponentSchema::CollectExternalData is a static function, and is not extendable by the schema.
In this case, the issue is that the actor component it is trying to resolve is only resolved via FindComponentByClass on the Owner, which is the AI controller. If the component is placed on the pawn, it will not find it through this function. I would expect external data dependencies to be resolvable to components on the controller and the pawn.
I will update this post as I find other issues.
Edit1:
With the struct ref fix above, you also need the following fix to FPropertyBindingBindingCollection::PerformCopy
[Image Removed]
This requires the delegate to change though, since the property is not guaranteed
[Image Removed] Edit2:
Related to context data resolution, I don’t know if this is new to 5.6, but I noticed while testing in 5.6 that I am getting state machine errors during
In AAIController::OnUnPossess(), there is a block to bStopAILogicOnUnposses, which stops the brain from ticking. Problem is, that Super::OnUnPossess(); has already been called, and so the Pawn has already been cleared. This means, that if the StateTree has a context property for the Pawn, or external data references to components that would normally live on the pawn, UStateTreeComponent::StopLogic will fail to stop the state tree, because the SetContextRequirements(Context) will fail, due to the Pawn already having been cleared. It seems reasonable to move the if (bStopAILogicOnUnposses) block to run above the Super::OnUnPossess(); Does that seem reasonable?