You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
"Call function" anim node: - Adds the ability to call functions at different points in the anim graph execution (and under different conditions, e.g. when a branch has started blending in). Only thread-safe functions are allowed to be called. - Adds a thread-safe override point BlueprintThreadSafeUpdateAnimation, called on worker threads for the main instance and for linked instances when they are relevant in the graph (only one call per frame for linked layer instances). Subsystems: - Added new override points pre/post event graph(s) (moved override point for worker thread work to around the thread safe update function call). Improves property access integration: - Property access now shows (and allows the user to override) the call site of accesses. This is to allow users to see when their property access calls will be made, hopefully making its use less confusing for power users. - Tweaked UX for property access nodes and dropdowns. - Anim node pins now have property access bindings in-line on the pin. Also adds the abilility for the anim graph to opt-in (via a config flag) to more stringent thread safety checks. Disabled by default for now as this requires content fixup. #jira UE-115745 - Anim Blueprint Encapsulation #rb Jurre.deBaare [CL 16434092 by Thomas Sarkanen in ue5-main branch]
100 lines
4.3 KiB
C++
100 lines
4.3 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "PropertyAccessAnimBlueprintBinding.h"
|
|
|
|
#include "AnimBlueprintExtension_PropertyAccess.h"
|
|
#include "AnimPropertyAccessUtils.h"
|
|
#include "Animation/AnimBlueprint.h"
|
|
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
|
#include "Framework/MultiBox/MultiBoxExtender.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "FPropertyAccessAnimBlueprintBinding"
|
|
|
|
bool FPropertyAccessAnimBlueprintBinding::CanBindToContext(const FContext& InContext) const
|
|
{
|
|
if(InContext.Blueprint)
|
|
{
|
|
return InContext.Blueprint->IsA<UAnimBlueprint>();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
TSharedPtr<FExtender> FPropertyAccessAnimBlueprintBinding::MakeBindingMenuExtender(const FContext& InContext, const FBindingMenuArgs& InArgs) const
|
|
{
|
|
TSharedPtr<FExtender> Extender = MakeShared<FExtender>();
|
|
Extender->AddMenuExtension("BindingActions", EExtensionHook::After, nullptr, FMenuExtensionDelegate::CreateLambda([InArgs](FMenuBuilder& InMenuBuilder)
|
|
{
|
|
InMenuBuilder.BeginSection("CallSite", LOCTEXT("CallSite", "Call Site"));
|
|
{
|
|
InMenuBuilder.AddSubMenu(
|
|
LOCTEXT("CallSite", "Call Site"),
|
|
LOCTEXT("CallSiteTooltip", "Choose when this property access value will be called & cached for later use when this graph is executed."),
|
|
FNewMenuDelegate::CreateLambda([InArgs](FMenuBuilder& InSubMenuBuilder)
|
|
{
|
|
InSubMenuBuilder.BeginSection("CallSiteSubMenu", LOCTEXT("CallSite", "Call Site"));
|
|
{
|
|
auto AddContextEntry = [InArgs, &InSubMenuBuilder](const FName& InContextId, const FText& InLabel, const FText& InToolTip)
|
|
{
|
|
InSubMenuBuilder.AddMenuEntry(
|
|
InLabel,
|
|
InToolTip,
|
|
FSlateIcon(),
|
|
FUIAction(
|
|
FExecuteAction::CreateLambda([InArgs, InContextId]()
|
|
{
|
|
InArgs.OnSetPropertyAccessContextId.ExecuteIfBound(InContextId);
|
|
}),
|
|
FCanExecuteAction::CreateLambda([InArgs, InContextId]()
|
|
{
|
|
if(InArgs.OnCanSetPropertyAccessContextId.IsBound())
|
|
{
|
|
return InArgs.OnCanSetPropertyAccessContextId.Execute(InContextId);
|
|
}
|
|
return false;
|
|
}),
|
|
FIsActionChecked::CreateLambda([InArgs, InContextId]()
|
|
{
|
|
const FName CurrentId = InArgs.OnGetPropertyAccessContextId.IsBound() ? InArgs.OnGetPropertyAccessContextId.Execute() : NAME_None;
|
|
return CurrentId == InContextId;
|
|
})),
|
|
NAME_None,
|
|
EUserInterfaceActionType::RadioButton
|
|
);
|
|
};
|
|
|
|
AddContextEntry(UAnimBlueprintExtension_PropertyAccess::ContextId_Automatic,
|
|
LOCTEXT("CallSiteAutomatic", "Automatic"),
|
|
LOCTEXT("CallSiteAutomatic_ToolTip", "Automatically determine the call site for this property access based on context and thread safety"));
|
|
|
|
AddContextEntry(UAnimBlueprintExtension_PropertyAccess::ContextId_UnBatched_ThreadSafe,
|
|
LOCTEXT("CallSiteThreadSafe", "Thread Safe"),
|
|
LOCTEXT("CallSiteThreadSafe_ToolTip", "Can safely be executed on worker threads"));
|
|
|
|
AddContextEntry(UAnimBlueprintExtension_PropertyAccess::ContextId_Batched_GameThreadPreEventGraph,
|
|
LOCTEXT("CallSiteGameThreadPreEventGraph", "Game Thread (Pre-Event Graph)"),
|
|
LOCTEXT("CallSiteGameThreadPreEventGraph_ToolTip", "Executed on the game thread before the event graph is run"));
|
|
|
|
AddContextEntry(UAnimBlueprintExtension_PropertyAccess::ContextId_Batched_GameThreadPostEventGraph,
|
|
LOCTEXT("CallSiteGameThreadPostEventGraph", "Game Thread (Post-Event Graph)"),
|
|
LOCTEXT("CallSiteGameThreadPostEventGraph_ToolTip", "Executed on the game thread after the event graph is run"));
|
|
|
|
AddContextEntry(UAnimBlueprintExtension_PropertyAccess::ContextId_Batched_WorkerThreadPreEventGraph,
|
|
LOCTEXT("CallSiteWorkerThreadPreEventGraph", "Worker Thread (Pre-Event Graph)"),
|
|
LOCTEXT("CallSiteWorkerThreadPreEventGraph_ToolTip", "Executed on a worker thread before the thread safe event graph is run"));
|
|
|
|
AddContextEntry(UAnimBlueprintExtension_PropertyAccess::ContextId_Batched_WorkerThreadPostEventGraph,
|
|
LOCTEXT("CallSiteWorkerThreadPostEventGraph", "Worker Thread (Post-Event Graph)"),
|
|
LOCTEXT("CallSiteWorkerThreadPostEventGraph_ToolTip", "Executed on a worker thread after the thread safe event graph is run"));
|
|
}
|
|
InSubMenuBuilder.EndSection();
|
|
})
|
|
);
|
|
}
|
|
InMenuBuilder.EndSection();
|
|
}));
|
|
return Extender;
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|