You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
+ Added StateTree parameters usable for data bindings and that could be overriden on context initialization by a StateTreeReference + Added StateTreeReference struct to hold a reference to a StateTree asset along with a list of values to parameterized the tree. + Added named external data items that are defined bt the Schema and for which values must be provided at runtime through the execution context. + Added delegate OnPostCompile after successful compilation. The StateTreeReference listens to it to validate its parameters + EditorData now contains its own version of the schema and parameters. On successful compilation they are copied over the StateTree own properties. #rnx #rb mikko.mononen #preflight 6255d281647ad886b3593cb0 [CL 19727363 by Yoan StAmant in ue5-main branch]
144 lines
4.9 KiB
C++
144 lines
4.9 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "StateTreeReference.h"
|
|
#include "StateTree.h"
|
|
#include "StateTreeDelegates.h"
|
|
#if WITH_EDITOR
|
|
#include "Editor.h"
|
|
#endif
|
|
|
|
#if WITH_EDITOR
|
|
void UStateTreeReferenceWrapper::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
|
|
{
|
|
UObject::PostEditChangeProperty(PropertyChangedEvent);
|
|
|
|
if (PropertyChangedEvent.MemberProperty && PropertyChangedEvent.Property)
|
|
{
|
|
if (PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(FStateTreeReference, StateTree))
|
|
{
|
|
StateTreeReference.SyncParameters();
|
|
}
|
|
}
|
|
}
|
|
|
|
void UStateTreeReferenceWrapper::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent)
|
|
{
|
|
UObject::PostEditChangeChainProperty(PropertyChangedEvent);
|
|
}
|
|
|
|
void UStateTreeReferenceWrapper::PostInitProperties()
|
|
{
|
|
UObject::PostInitProperties();
|
|
|
|
// Registers a delegate to be notified when the associated StateTree asset get successfully recompiled
|
|
// to make sure that the parameters in the StateTreeReference are still valid.
|
|
PostCompileHandle = UE::StateTree::Delegates::OnPostCompile.AddLambda([this](const UStateTree& InStateTree)
|
|
{
|
|
if (StateTreeReference.StateTree == &InStateTree)
|
|
{
|
|
if (StateTreeReference.SyncParameters())
|
|
{
|
|
MarkPackageDirty();
|
|
}
|
|
}
|
|
});
|
|
|
|
// Make sure any modifications to the parameters since the last sync (PostLoad) won't cause runtime issues.
|
|
// This shouldn't be necessary if only parameters values could be modified but until that is enforce this will
|
|
// prevent parameters inconsistencies at runtime.
|
|
PIEHandle = FEditorDelegates::PreBeginPIE.AddLambda([this](const bool bBegan)
|
|
{
|
|
const bool bModified = StateTreeReference.SyncParameters();
|
|
UE_CLOG(bModified, LogStateTree, Warning, TEXT("Parameters for StateTree '%s' stored in %s were auto-fixed to be usable at runtime."),
|
|
*GetNameSafe(StateTreeReference.StateTree), *GetName());
|
|
});
|
|
}
|
|
|
|
void UStateTreeReferenceWrapper::PostLoad()
|
|
{
|
|
UObject::PostLoad();
|
|
|
|
// This might modify the object but we don't want to dirty on load
|
|
StateTreeReference.SyncParameters();
|
|
}
|
|
|
|
void UStateTreeReferenceWrapper::BeginDestroy()
|
|
{
|
|
UObject::BeginDestroy();
|
|
|
|
// Unregister all our delegates
|
|
UE::StateTree::Delegates::OnPostCompile.Remove(PostCompileHandle);
|
|
FEditorDelegates::PreBeginPIE.Remove(PIEHandle);
|
|
}
|
|
|
|
bool FStateTreeReference::SyncParameters()
|
|
{
|
|
TArray<FStateTreeParameterDesc>& Params = Parameters.Parameters;
|
|
if (StateTree == nullptr)
|
|
{
|
|
const bool bHadParameters = !Params.IsEmpty();
|
|
Params.Reset();
|
|
return bHadParameters;
|
|
}
|
|
|
|
// First implementation is to make sure that the StateTreeReference holds values for each parameter of the StateTree.
|
|
// This is the easiest way to expose them to the user but that also means that user can't specify only a subset of parameters
|
|
// and use default value for the others.
|
|
const TConstArrayView<FStateTreeParameterDesc> AssetParameters = StateTree ? StateTree->GetParameterDescs() : TConstArrayView<FStateTreeParameterDesc>();
|
|
bool bAreParametersSynced = AssetParameters.Num() == Params.Num();
|
|
if (bAreParametersSynced)
|
|
{
|
|
for (int32 i = 0; i < Params.Num(); ++i)
|
|
{
|
|
if (!Params[i].IsMatching(AssetParameters[i]))
|
|
{
|
|
// Ok to mismatch only by the name if both ID and Type match. Simply update it since
|
|
// it must also match when passed to the ExecutionContext at runtime.
|
|
if (Params[i].ID == AssetParameters[i].ID && Params[i].IsSameType(AssetParameters[i]))
|
|
{
|
|
UE_LOG(LogStateTree, Warning, TEXT("StateTree parameter '%s' name was updated to match StateTree parameter '%s'."),
|
|
*LexToString(Params[i]), *LexToString(AssetParameters[i]));
|
|
|
|
Params[i].Name = AssetParameters[i].Name;
|
|
checkf(Params[i].IsMatching(AssetParameters[i]),
|
|
TEXT("After fixing the name the parameters should match."
|
|
" If this fails it indicates that same ID+Type is no longer the only required condition."));
|
|
}
|
|
else
|
|
{
|
|
bAreParametersSynced = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bAreParametersSynced)
|
|
{
|
|
TArray<FStateTreeParameterDesc> DeprecatedParameters = MoveTemp(Params);
|
|
Params = AssetParameters;
|
|
|
|
for (int32 i = 0; i < Params.Num(); ++i)
|
|
{
|
|
FStateTreeParameterDesc& ParameterDesc = Params[i];
|
|
|
|
// Find parameter corresponding index in the deprecated parameters using 'Type' and 'Id'.
|
|
// Not using IsMatching() here since 'Name' might have change in addition to parameters added/removed since the last sync.
|
|
const int32 IndexInDeprecated = DeprecatedParameters.IndexOfByPredicate([&ParameterDesc](const FStateTreeParameterDesc& DeprecatedDesc)
|
|
{
|
|
return DeprecatedDesc.ID == ParameterDesc.ID && DeprecatedDesc.IsSameType(ParameterDesc);
|
|
});
|
|
|
|
if (IndexInDeprecated != INDEX_NONE)
|
|
{
|
|
// Only update value
|
|
ParameterDesc.Parameter = DeprecatedParameters[IndexInDeprecated].Parameter;
|
|
DeprecatedParameters.RemoveAtSwap(IndexInDeprecated);
|
|
}
|
|
}
|
|
}
|
|
|
|
return !bAreParametersSynced;
|
|
}
|
|
#endif // WITH_EDITOR
|