You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
264 lines
8.5 KiB
C++
264 lines
8.5 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "K2Node_MatineeController.h"
|
|
#include "EdGraphSchema_K2.h"
|
|
#include "K2Node_Event.h"
|
|
#include "Kismet2/BlueprintEditorUtils.h"
|
|
|
|
#include "BlueprintNodeBinder.h"
|
|
#include "BlueprintActionDatabaseRegistrar.h"
|
|
#include "BlueprintBoundNodeSpawner.h"
|
|
#include "KismetCompiler.h"
|
|
#include "MatineeDelegates.h"
|
|
#include "Matinee/MatineeActor.h"
|
|
#include "Matinee/InterpData.h"
|
|
|
|
UK2Node_MatineeController::UK2Node_MatineeController(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
if (GetOutermost() != GetTransientPackage())
|
|
{
|
|
// Register the delegate ONLY if this isn't the transient package (temp node during compilation)
|
|
FMatineeDelegates::Get().OnEventKeyframeAdded.AddUObject(this, &UK2Node_MatineeController::OnEventKeyframeAdded);
|
|
FMatineeDelegates::Get().OnEventKeyframeRenamed.AddUObject(this, &UK2Node_MatineeController::OnEventKeyframeRenamed);
|
|
FMatineeDelegates::Get().OnEventKeyframeRemoved.AddUObject(this, &UK2Node_MatineeController::OnEventKeyframeRemoved);
|
|
}
|
|
}
|
|
|
|
void UK2Node_MatineeController::BeginDestroy()
|
|
{
|
|
Super::BeginDestroy();
|
|
|
|
FMatineeDelegates::Get().OnEventKeyframeAdded.RemoveAll(this);
|
|
FMatineeDelegates::Get().OnEventKeyframeRenamed.RemoveAll(this);
|
|
FMatineeDelegates::Get().OnEventKeyframeRemoved.RemoveAll(this);
|
|
}
|
|
|
|
void UK2Node_MatineeController::AllocateDefaultPins()
|
|
{
|
|
// Preload the matinee data, if needed, so that we can have all the event tracks we need
|
|
if (MatineeActor)
|
|
{
|
|
PreloadObject(MatineeActor);
|
|
PreloadObject(MatineeActor->MatineeData);
|
|
}
|
|
|
|
// Create the "finished" playing pin
|
|
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_MatineeFinished);
|
|
|
|
// Create pins for each event
|
|
if (MatineeActor && MatineeActor->MatineeData)
|
|
{
|
|
TArray<FName> EventNames;
|
|
MatineeActor->MatineeData->GetAllEventNames(EventNames);
|
|
|
|
for (const FName& EventName : EventNames)
|
|
{
|
|
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, EventName);
|
|
}
|
|
}
|
|
|
|
Super::AllocateDefaultPins();
|
|
}
|
|
|
|
void UK2Node_MatineeController::PreloadRequiredAssets()
|
|
{
|
|
if(MatineeActor)
|
|
{
|
|
PreloadObject(MatineeActor);
|
|
PreloadObject(MatineeActor->MatineeData);
|
|
}
|
|
Super::PreloadRequiredAssets();
|
|
}
|
|
|
|
FLinearColor UK2Node_MatineeController::GetNodeTitleColor() const
|
|
{
|
|
return FLinearColor(1.0f, 0.51f, 0.0f);
|
|
}
|
|
|
|
|
|
FText UK2Node_MatineeController::GetNodeTitle(ENodeTitleType::Type TitleType) const
|
|
{
|
|
if(MatineeActor != NULL)
|
|
{
|
|
return FText::FromString(MatineeActor->GetActorLabel());
|
|
}
|
|
else
|
|
{
|
|
return NSLOCTEXT("K2Node", "InvalidMatineeController", "INVALID MATINEECONTROLLER");
|
|
}
|
|
}
|
|
|
|
AActor* UK2Node_MatineeController::GetReferencedLevelActor() const
|
|
{
|
|
return MatineeActor;
|
|
}
|
|
|
|
UEdGraphPin* UK2Node_MatineeController::GetFinishedPin() const
|
|
{
|
|
return FindPin(UEdGraphSchema_K2::PN_MatineeFinished);
|
|
}
|
|
|
|
void UK2Node_MatineeController::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph)
|
|
{
|
|
if (SourceGraph != CompilerContext.ConsolidatedEventGraph)
|
|
{
|
|
CompilerContext.MessageLog.Error(*NSLOCTEXT("KismetCompiler", "InvalidNodeOutsideUbergraph_Error", "Unexpected node @@ found outside ubergraph.").ToString(), this);
|
|
return;
|
|
}
|
|
|
|
Super::ExpandNode(CompilerContext, SourceGraph);
|
|
|
|
if (MatineeActor != NULL)
|
|
{
|
|
UFunction* MatineeEventSig = FindObject<UFunction>(AMatineeActor::StaticClass(), TEXT("OnMatineeEvent__DelegateSignature"));
|
|
check(MatineeEventSig != NULL);
|
|
|
|
const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema();
|
|
|
|
// Create event for each exec output pin
|
|
for(int32 PinIdx=0; PinIdx<Pins.Num(); PinIdx++)
|
|
{
|
|
UEdGraphPin* MatineePin = Pins[PinIdx];
|
|
if(MatineePin->Direction == EGPD_Output && MatineePin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec)
|
|
{
|
|
FName EventFuncName = MatineeActor->GetFunctionNameForEvent(MatineePin->PinName);
|
|
|
|
UK2Node_Event* MatineeEventNode = CompilerContext.SpawnIntermediateEventNode<UK2Node_Event>(this, MatineePin, SourceGraph);
|
|
MatineeEventNode->EventReference.SetFromField<UFunction>(MatineeEventSig, false);
|
|
MatineeEventNode->CustomFunctionName = EventFuncName;
|
|
MatineeEventNode->bInternalEvent = true;
|
|
MatineeEventNode->AllocateDefaultPins();
|
|
|
|
// Move connection from matinee output to event node output
|
|
UEdGraphPin* EventOutputPin = Schema->FindExecutionPin(*MatineeEventNode, EGPD_Output);
|
|
check(EventOutputPin != NULL);
|
|
CompilerContext.MovePinLinksToIntermediate(*MatineePin, *EventOutputPin);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UK2Node_MatineeController::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
|
|
{
|
|
UClass* ActionKey = GetClass();
|
|
if (!ActionRegistrar.IsOpenForRegistration(ActionKey))
|
|
{
|
|
return;
|
|
}
|
|
|
|
auto CanBindObjectLambda = [](UObject const* BindingObject)
|
|
{
|
|
if (AMatineeActor const* Actor = Cast<AMatineeActor>(BindingObject))
|
|
{
|
|
// Make sure the Actor has a world
|
|
if (Actor->GetWorld())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
auto UiSpecOverride = [](const FBlueprintActionContext& /*Context*/, const IBlueprintNodeBinder::FBindingSet& Bindings, FBlueprintActionUiSpec* UiSpecOut)
|
|
{
|
|
if (Bindings.Num() == 1)
|
|
{
|
|
UiSpecOut->MenuName = FText::Format(NSLOCTEXT("K2Node", "MatineeeControllerTitle", "Create a Matinee Controller for {0}"),
|
|
FText::FromString((*(Bindings.CreateConstIterator())).GetName()));
|
|
}
|
|
else if (Bindings.Num() > 1)
|
|
{
|
|
UiSpecOut->MenuName = FText::Format(NSLOCTEXT("K2Node", "MultipleMatineeeControllerTitle", "Create Matinee Controllers for {0} selected MatineeActors"),
|
|
FText::AsNumber(Bindings.Num()));
|
|
}
|
|
else
|
|
{
|
|
UiSpecOut->MenuName = NSLOCTEXT("K2Node", "FallbackMatineeeControllerTitle", "Error: No MatineeActors in Context");
|
|
}
|
|
};
|
|
|
|
auto PostBindSetupLambda = [](UEdGraphNode* NewNode, UObject* BindObject)
|
|
{
|
|
UK2Node_MatineeController* MatineeNode = CastChecked<UK2Node_MatineeController>(NewNode);
|
|
MatineeNode->MatineeActor = CastChecked<AMatineeActor>(BindObject);
|
|
MatineeNode->MatineeActor->MatineeControllerName = MatineeNode->GetFName();
|
|
return true;
|
|
};
|
|
|
|
auto FindPreExistingNodeLambda = []( const UBlueprint* Blueprint, IBlueprintNodeBinder::FBindingSet const& BindingSet ) -> UEdGraphNode*
|
|
{
|
|
TArray<UK2Node_MatineeController*> ExistingMatineeControllers;
|
|
FBlueprintEditorUtils::GetAllNodesOfClass(Blueprint, ExistingMatineeControllers);
|
|
for (auto Controller : ExistingMatineeControllers)
|
|
{
|
|
if (BindingSet.Contains( Controller->MatineeActor ))
|
|
{
|
|
return Controller;
|
|
}
|
|
}
|
|
return nullptr;
|
|
};
|
|
|
|
UBlueprintBoundNodeSpawner* NodeSpawner = UBlueprintBoundNodeSpawner::Create(GetClass());
|
|
NodeSpawner->CanBindObjectDelegate = UBlueprintBoundNodeSpawner::FCanBindObjectDelegate::CreateStatic(CanBindObjectLambda);
|
|
NodeSpawner->OnBindObjectDelegate = UBlueprintBoundNodeSpawner::FOnBindObjectDelegate::CreateStatic(PostBindSetupLambda);
|
|
NodeSpawner->DynamicUiSignatureGetter = UBlueprintBoundNodeSpawner::FUiSpecOverrideDelegate::CreateStatic(UiSpecOverride);
|
|
NodeSpawner->FindPreExistingNodeDelegate = UBlueprintBoundNodeSpawner::FFindPreExistingNodeDelegate::CreateStatic( FindPreExistingNodeLambda );
|
|
ActionRegistrar.AddBlueprintAction(ActionKey, NodeSpawner);
|
|
}
|
|
|
|
void UK2Node_MatineeController::OnEventKeyframeAdded(const AMatineeActor* InMatineeActor, const FName& InPinName, int32 InIndex)
|
|
{
|
|
if ( MatineeActor == InMatineeActor )
|
|
{
|
|
// Only add unique event names to the controller node
|
|
if (!FindPin(InPinName))
|
|
{
|
|
// Add one to the index as we insert "finished" at index 0
|
|
UEdGraphNode::FCreatePinParams PinParams;
|
|
PinParams.Index = InIndex + 1;
|
|
CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, InPinName, PinParams);
|
|
|
|
// Update and refresh the blueprint
|
|
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(GetBlueprint());
|
|
}
|
|
}
|
|
}
|
|
|
|
void UK2Node_MatineeController::OnEventKeyframeRenamed(const AMatineeActor* InMatineeActor, const FName& InOldPinName, const FName& InNewPinName)
|
|
{
|
|
if ( MatineeActor == InMatineeActor )
|
|
{
|
|
if( UEdGraphPin* OldPin = FindPin(InOldPinName) )
|
|
{
|
|
OldPin->Modify();
|
|
OldPin->PinName = InNewPinName;
|
|
|
|
GetGraph()->NotifyGraphChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
void UK2Node_MatineeController::OnEventKeyframeRemoved(const AMatineeActor* InMatineeActor, const TArray<FName>& InPinNames)
|
|
{
|
|
if ( MatineeActor == InMatineeActor )
|
|
{
|
|
bool bNeedsRefresh = false;
|
|
for(int32 PinIdx=0; PinIdx<InPinNames.Num(); PinIdx++)
|
|
{
|
|
if(UEdGraphPin* Pin = FindPin(InPinNames[PinIdx]))
|
|
{
|
|
RemovePin(Pin);
|
|
bNeedsRefresh = true;
|
|
}
|
|
}
|
|
|
|
if ( bNeedsRefresh )
|
|
{
|
|
// Update and refresh the blueprint
|
|
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(GetBlueprint());
|
|
}
|
|
}
|
|
}
|