diff --git a/Content/Editor/Slate/Icons/ComboAction_16.svg b/Content/Editor/Slate/Icons/ComboAction_16.svg new file mode 100644 index 0000000..949ec54 --- /dev/null +++ b/Content/Editor/Slate/Icons/ComboAction_16.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/Content/Editor/Slate/Icons/ComboAction_64.svg b/Content/Editor/Slate/Icons/ComboAction_64.svg new file mode 100644 index 0000000..b89cd84 --- /dev/null +++ b/Content/Editor/Slate/Icons/ComboAction_64.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content/Editor/Slate/Icons/ComboInputAsset_16.svg b/Content/Editor/Slate/Icons/ComboInputAsset_16.svg new file mode 100644 index 0000000..be35b0c --- /dev/null +++ b/Content/Editor/Slate/Icons/ComboInputAsset_16.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Content/Editor/Slate/Icons/ComboInputAsset_64.svg b/Content/Editor/Slate/Icons/ComboInputAsset_64.svg new file mode 100644 index 0000000..1993590 --- /dev/null +++ b/Content/Editor/Slate/Icons/ComboInputAsset_64.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content/Editor/Slate/Icons/ComboInput_16.svg b/Content/Editor/Slate/Icons/ComboInput_16.svg new file mode 100644 index 0000000..ff775db --- /dev/null +++ b/Content/Editor/Slate/Icons/ComboInput_16.svg @@ -0,0 +1,4 @@ + + + + diff --git a/Content/Editor/Slate/Icons/ComboInput_64.svg b/Content/Editor/Slate/Icons/ComboInput_64.svg new file mode 100644 index 0000000..611be0f --- /dev/null +++ b/Content/Editor/Slate/Icons/ComboInput_64.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/Content/Editor/Slate/Icons/ComboSequenceNode_16.svg b/Content/Editor/Slate/Icons/ComboSequenceNode_16.svg new file mode 100644 index 0000000..b20ea71 --- /dev/null +++ b/Content/Editor/Slate/Icons/ComboSequenceNode_16.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Content/Editor/Slate/Icons/ComboSequenceNode_64.svg b/Content/Editor/Slate/Icons/ComboSequenceNode_64.svg new file mode 100644 index 0000000..4a109ec --- /dev/null +++ b/Content/Editor/Slate/Icons/ComboSequenceNode_64.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/ComboInput/ComboInput.Build.cs b/Source/ComboInput/ComboInput.Build.cs index ea0378a..546d216 100644 --- a/Source/ComboInput/ComboInput.Build.cs +++ b/Source/ComboInput/ComboInput.Build.cs @@ -50,6 +50,7 @@ public class ComboInput : ModuleRules "BlueprintGraph", "GraphEditor", + "KismetCompiler", } ); diff --git a/Source/ComboInput/Private/Components/ComboManagerComponent.cpp b/Source/ComboInput/Private/Components/ComboManagerComponent.cpp index 890cad1..56644f0 100644 --- a/Source/ComboInput/Private/Components/ComboManagerComponent.cpp +++ b/Source/ComboInput/Private/Components/ComboManagerComponent.cpp @@ -70,6 +70,11 @@ void UComboManagerComponent::ActivateComboInput(const UComboInputAsset *Input) { this->BeginNodeTransition(ActionData.NextNode); + for (const FComboActionHandlerDynamicSignature &Binding : this->ComboActionEventBindings) + { + Binding.Execute(/*EComboActionTriggerEvent::Activated*/); + } + UE_LOG(LogComboManagerComponent, Verbose, TEXT("%s activated"), *ActionData.ComboAction->ActionName.ToString()); } } diff --git a/Source/ComboInput/Private/Events/ComboActionDelegateBinding.cpp b/Source/ComboInput/Private/Events/ComboActionDelegateBinding.cpp index eb1d377..0021cf1 100644 --- a/Source/ComboInput/Private/Events/ComboActionDelegateBinding.cpp +++ b/Source/ComboInput/Private/Events/ComboActionDelegateBinding.cpp @@ -2,6 +2,10 @@ #include "Events/ComboActionDelegateBinding.h" +#include "EnhancedInputComponent.h" +#include "Components/ComboManagerComponent.h" +#include "GameFramework/PlayerController.h" + #include UE_INLINE_GENERATED_CPP_BY_NAME(ComboActionDelegateBinding) @@ -10,7 +14,23 @@ UComboActionDelegateBinding::UComboActionDelegateBinding(const FObjectInitialize { } -void UComboActionDelegateBinding::BindToComboManagerComponent(UComboManagerComponent *ComboManager, UObject *ObjectToBindTo) const +void UComboActionDelegateBinding::BindDynamicDelegates(UObject *InInstance) const { - + APlayerController *PlayerController = Cast(InInstance); + if (!PlayerController) + { + return; + } + + if (UComboManagerComponent *ComboManager = PlayerController->GetComponentByClass()) + { + for (const FBlueprintComboActionBinding &Binding : this->ComboActionDelegateBindings) + { + // Get the function we want to bind + if (UFunction *FunctionToBind = InInstance->GetClass()->FindFunctionByName(Binding.FunctionNameToBind)) + { + ComboManager->BindAction(InInstance, Binding.FunctionNameToBind); + } + } + } } diff --git a/Source/ComboInput/Private/Events/K2Node_ComboAction.cpp b/Source/ComboInput/Private/Events/K2Node_ComboAction.cpp index 7b0f065..b2b3414 100644 --- a/Source/ComboInput/Private/Events/K2Node_ComboAction.cpp +++ b/Source/ComboInput/Private/Events/K2Node_ComboAction.cpp @@ -7,6 +7,7 @@ #include "BlueprintEditorSettings.h" #include "BlueprintNodeSpawner.h" #include "ComboInputAssets.h" +#include "ComboInputTriggers.h" #include "EdGraphSchema_K2_Actions.h" #include "Editor.h" #include "EditorCategoryUtils.h" @@ -21,9 +22,6 @@ #include "Modules/ModuleManager.h" #include "Styling/AppStyle.h" -#define ACTIVATED_PIN_NAME TEXT("Activated") -#define COMBO_ACTION_PIN_NAME TEXT("Combo Action") - #include UE_INLINE_GENERATED_CPP_BY_NAME(K2Node_ComboAction) #define LOCTEXT_NAMESPACE "K2Node_ComboAction" @@ -44,14 +42,14 @@ UK2Node_ComboAction::UK2Node_ComboAction(const FObjectInitializer &ObjectInitial { } -void ForEachEventPinName(TFunctionRef PinLambda) +void ForEachEventPinName(TFunctionRef PinLambda) { - UEnum* EventEnum = StaticEnum(); + UEnum *EventEnum = StaticEnum(); for (int32 i = 0; i < EventEnum->NumEnums() - 1; ++i) { if (!EventEnum->HasMetaData(TEXT("Hidden"), i)) { - PinLambda(ETriggerEvent(EventEnum->GetValueByIndex(i)), *EventEnum->GetNameStringByIndex(i)); + PinLambda(EComboActionTriggerEvent(EventEnum->GetValueByIndex(i)), *EventEnum->GetNameStringByIndex(i)); } } } @@ -60,66 +58,19 @@ void UK2Node_ComboAction::AllocateDefaultPins() { this->PreloadObject((UObject*)this->ComboAction); - UEdGraphPin *TriggeredPin = this->CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, TEXT("Triggered")); - TriggeredPin->PinToolTip = TEXT("Executed when this combo action is first activated."); - - // Add a special tooltip and display name for pins that are unsupported - if (UE::Input::bComboActionShouldWarnOnUnsupportedInputPin) + ForEachEventPinName([this](EComboActionTriggerEvent Event, FName PinName) { - static const FText UnsuportedTooltip = LOCTEXT("UnsupportedTooltip", "\n\nThis trigger event is not supported by the action! Add a supported trigger to enable this pin."); - TriggeredPin->PinToolTip += UnsuportedTooltip.ToString(); - TriggeredPin->PinFriendlyName = FText::Format(LOCTEXT("UnsupportedPinFriendlyName", "(Unsupported) {0}"), FText::FromName(TriggeredPin->GetFName())); - } - - HideEventPins(nullptr); - const UEdGraphSchema_K2 *Schema = GetDefault(); - - this->AdvancedPinDisplay = ENodeAdvancedPins::Hidden; - - UEdGraphPin *ActivatedValuePin = this->CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Boolean, UEdGraphSchema_K2::PC_Boolean, ACTIVATED_PIN_NAME); - ActivatedValuePin->bAdvancedView = true; - Schema->SetPinAutogeneratedDefaultValue(ActivatedValuePin, TEXT("true")); + static const UEnum *EventEnum = StaticEnum(); - if(this->ComboAction) - { - UEdGraphPin *ActionPin = CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Object, this->ComboAction->GetClass(), COMBO_ACTION_PIN_NAME); - ActionPin->DefaultObject = const_cast(Cast(ComboAction)); - ActionPin->DefaultValue = ComboAction->GetName(); - Schema->ConstructBasicPinTooltip(*ActionPin, LOCTEXT("InputActionPinDescription", "The input action that caused this event to fire"), ActionPin->PinToolTip); - } + UEdGraphPin *NewPin = CreatePin(EEdGraphPinDirection::EGPD_Output, UEdGraphSchema_K2::PC_Exec, PinName); + NewPin->PinToolTip = EventEnum->GetToolTipTextByIndex(EventEnum->GetIndexByValue(static_cast(Event))).ToString(); + }); + + this->AdvancedPinDisplay = ENodeAdvancedPins::NoPins; Super::AllocateDefaultPins(); } -void UK2Node_ComboAction::HideEventPins(UEdGraphPin *RetainPin) -{ - //// Gather pins - //const ETriggerEventsSupported SupportedTriggerEvents = GetDefault()->bEnableInputTriggerSupportWarnings && InputAction ? InputAction->GetSupportedTriggerEvents() : ETriggerEventsSupported::All; - - //// Hide any event pins that are not supported by this Action's triggers in the advanced view - //ForEachEventPinName([this, SupportedTriggerEvents](ETriggerEvent Event, FName PinName) - //{ - // if (UEdGraphPin* Pin = FindPin(PinName)) - // { - // const bool bIsSupported = UInputTrigger::IsSupportedTriggerEvent(SupportedTriggerEvents, Event); - // - // Pin->bAdvancedView = !bIsSupported; - // } - //}); -} - -void UK2Node_ComboAction::PostReconstructNode() -{ - Super::PostReconstructNode(); - HideEventPins(nullptr); -} - -void UK2Node_ComboAction::PinConnectionListChanged(UEdGraphPin* Pin) -{ - Super::PinConnectionListChanged(Pin); - HideEventPins(Pin); -} - FLinearColor UK2Node_ComboAction::GetNodeTitleColor() const { return GetDefault()->EventNodeTitleColor; @@ -127,7 +78,7 @@ FLinearColor UK2Node_ComboAction::GetNodeTitleColor() const FName UK2Node_ComboAction::GetActionName() const { - return this->ComboAction ? this->ComboAction->GetFName() : FName(); + return this->ComboAction ? this->ComboAction->ActionName : FName(); } FText UK2Node_ComboAction::GetNodeTitle(ENodeTitleType::Type TitleType) const @@ -210,135 +161,69 @@ void UK2Node_ComboAction::ValidateNodeDuringCompilation(class FCompilerResultsLo } } -void UK2Node_ComboAction::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) +void UK2Node_ComboAction::ExpandNode(FKismetCompilerContext &CompilerContext, UEdGraph *SourceGraph) { Super::ExpandNode(CompilerContext, SourceGraph); if(!this->ComboAction) { - static const FText InvalidActionWarning = LOCTEXT("InvalidInputActionDuringExpansion", "@@ does not have a valid Input Action asset!!"); + static const FText InvalidActionWarning = LOCTEXT("InvalidComboActionDuringExpansion", "@@ does not have a valid Combo Action asset!!"); CompilerContext.MessageLog.Warning(*InvalidActionWarning.ToString(), this); return; } - //// Establish active pins - //struct ActivePinData - //{ - // ActivePinData(UEdGraphPin* InPin, ETriggerEvent InTriggerEvent) : Pin(InPin), TriggerEvent(InTriggerEvent) {} - // UEdGraphPin* Pin; - // ETriggerEvent TriggerEvent; - //}; + // Establish active pins + struct ActivePinData + { + ActivePinData(UEdGraphPin* InPin, EComboActionTriggerEvent InTriggerEvent) : Pin(InPin), TriggerEvent(InTriggerEvent) {} + UEdGraphPin* Pin; + EComboActionTriggerEvent TriggerEvent; + }; - //const ETriggerEventsSupported SupportedTriggerEvents = GetDefault()->bEnableInputTriggerSupportWarnings ? this->ComboAction->GetSupportedTriggerEvents() : ETriggerEventsSupported::All; - // - //TArray ActivePins; - //ForEachEventPinName([this, &ActivePins, &SupportedTriggerEvents, &CompilerContext](ETriggerEvent Event, FName PinName) - //{ - // UEdGraphPin* ComboActionPin = FindPin(PinName, EEdGraphPinDirection::EGPD_Output); - // if (ComboActionPin && ComboActionPin->LinkedTo.Num() > 0) - // { - // ActivePins.Add(ActivePinData(ComboActionPin, Event)); - // // Check if this exec pin is supported! - // if (UE::Input::bShouldWarnOnUnsupportedInputPin && !UInputTrigger::IsSupportedTriggerEvent(SupportedTriggerEvents, Event)) - // { - // CompilerContext.MessageLog.Warning(*FText::Format(LOCTEXT("UnsuportedEventTypeOnAction", "'{0}'on @@ may not be executed because it is not a supported trigger on this action!"), ComboActionPin->GetDisplayName()).ToString(), this); - // } - // } - //}); + TArray ActivePins; + ForEachEventPinName([this, &ActivePins, &CompilerContext](EComboActionTriggerEvent Event, FName PinName) + { + UEdGraphPin *ComboActionPin = FindPin(PinName, EEdGraphPinDirection::EGPD_Output); + if (ComboActionPin && ComboActionPin->LinkedTo.Num() > 0) + { + ActivePins.Add(ActivePinData(ComboActionPin, Event)); + } + }); - //if (ActivePins.Num() == 0) - //{ - // return; - //} + if (ActivePins.Num() == 0) + { + return; + } - //// Bind all active pins to their action delegate - //const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema(); + // Bind all active pins to their action delegate + const UEdGraphSchema_K2 *Schema = CompilerContext.GetSchema(); - //auto CreateComboActionEvent = [this, &CompilerContext, &SourceGraph](UEdGraphPin* Pin, ETriggerEvent TriggerEvent) -> UK2Node_ComboActionEvent* - //{ - // if (!this->ComboAction) - // { - // return nullptr; - // } + auto CreateComboActionEvent = [this, &CompilerContext, &SourceGraph](UEdGraphPin *Pin, EComboActionTriggerEvent TriggerEvent) -> UK2Node_ComboActionEvent * + { + if (!this->ComboAction) + { + return nullptr; + } - // UK2Node_ComboActionEvent* InputActionEvent = CompilerContext.SpawnIntermediateEventNode(this, Pin, SourceGraph); - // InputActionEvent->CustomFunctionName = FName(*FString::Printf(TEXT("InpActEvt_%s_%s"), *GetActionName().ToString(), *InputActionEvent->GetName())); - // InputActionEvent->ComboAction = this->ComboAction; - // InputActionEvent->TriggerEvent = TriggerEvent; - // InputActionEvent->EventReference.SetExternalDelegateMember(FName(TEXT("ComboActionHandlerDynamicSignature__DelegateSignature"))); - // InputActionEvent->AllocateDefaultPins(); - // return InputActionEvent; - //}; + UK2Node_ComboActionEvent *ComboActionEvent = CompilerContext.SpawnIntermediateEventNode(this, Pin, SourceGraph); + ComboActionEvent->CustomFunctionName = FName(*FString::Printf(TEXT("ComboActionEvent_%s_%s"), *this->ComboAction->GetName(), *ComboActionEvent->GetName())); + ComboActionEvent->ComboAction = this->ComboAction; + ComboActionEvent->TriggerEvent = TriggerEvent; + ComboActionEvent->EventReference.SetExternalDelegateMember(FName(TEXT("ComboActionHandlerDynamicSignature__DelegateSignature"))); + ComboActionEvent->AllocateDefaultPins(); + return ComboActionEvent; + }; - //// Create temporary variables to copy ActionValue and ElapsedSeconds into - //UK2Node_TemporaryVariable* ActionValueVar = CompilerContext.SpawnIntermediateNode(this, SourceGraph); - //ActionValueVar->VariableType.PinCategory = UK2Node_GetInputActionValue::GetValueCategory(this->ComboAction); - //ActionValueVar->VariableType.PinSubCategory = UK2Node_GetInputActionValue::GetValueSubCategory(this->ComboAction); - //ActionValueVar->VariableType.PinSubCategoryObject = UK2Node_GetInputActionValue::GetValueSubCategoryObject(this->ComboAction); - //ActionValueVar->AllocateDefaultPins(); + for (ActivePinData &PinData : ActivePins) + { + UEdGraphPin *EachPin = PinData.Pin; + UK2Node_ComboActionEvent *ComboActionEvent = CreateComboActionEvent(EachPin, PinData.TriggerEvent); - //UK2Node_TemporaryVariable* ElapsedSecondsVar = CompilerContext.SpawnIntermediateNode(this, SourceGraph); - //ElapsedSecondsVar->VariableType.PinCategory = UEdGraphSchema_K2::PC_Real; - //ElapsedSecondsVar->VariableType.PinSubCategory = UEdGraphSchema_K2::PC_Double; - //ElapsedSecondsVar->AllocateDefaultPins(); - //UK2Node_TemporaryVariable* TriggeredSecondsVar = CompilerContext.SpawnIntermediateNode(this, SourceGraph); - //TriggeredSecondsVar->VariableType.PinCategory = UEdGraphSchema_K2::PC_Real; - //TriggeredSecondsVar->VariableType.PinSubCategory = UEdGraphSchema_K2::PC_Double; - //TriggeredSecondsVar->AllocateDefaultPins(); - - //UK2Node_TemporaryVariable* InputActionVar = CompilerContext.SpawnIntermediateNode(this, SourceGraph); - //InputActionVar->VariableType.PinCategory = UEdGraphSchema_K2::PC_Object; - //InputActionVar->VariableType.PinSubCategoryObject = this->ComboAction->GetClass(); - //InputActionVar->AllocateDefaultPins(); - - //for (ActivePinData& PinData : ActivePins) - //{ - // UEdGraphPin* EachPin = PinData.Pin; - // UK2Node_ComboActionEvent *ComboActionEvent = CreateComboActionEvent(EachPin, PinData.TriggerEvent); - - // if (!ComboActionEvent) - // { - // continue; - // } - - // // Create assignment nodes to assign the action value - // UK2Node_AssignmentStatement* ActionValueInitialize = CompilerContext.SpawnIntermediateNode(this, SourceGraph); - // ActionValueInitialize->AllocateDefaultPins(); - // Schema->TryCreateConnection(ActionValueVar->GetVariablePin(), ActionValueInitialize->GetVariablePin()); - // Schema->TryCreateConnection(ActionValueInitialize->GetValuePin(), ComboActionEvent->FindPinChecked(ActionValuePinName)); - // // Connect the events to the assign location nodes - // Schema->TryCreateConnection(Schema->FindExecutionPin(*ComboActionEvent, EGPD_Output), ActionValueInitialize->GetExecPin()); - - // // Create assignment nodes to assign the elapsed timers and input action - // UK2Node_AssignmentStatement* ElapsedSecondsInitialize = CompilerContext.SpawnIntermediateNode(this, SourceGraph); - // ElapsedSecondsInitialize->AllocateDefaultPins(); - // Schema->TryCreateConnection(ElapsedSecondsVar->GetVariablePin(), ElapsedSecondsInitialize->GetVariablePin()); - // Schema->TryCreateConnection(ElapsedSecondsInitialize->GetValuePin(), ComboActionEvent->FindPinChecked(TEXT("ElapsedTime"))); - - // UK2Node_AssignmentStatement* TriggeredSecondsInitialize = CompilerContext.SpawnIntermediateNode(this, SourceGraph); - // TriggeredSecondsInitialize->AllocateDefaultPins(); - // Schema->TryCreateConnection(TriggeredSecondsVar->GetVariablePin(), TriggeredSecondsInitialize->GetVariablePin()); - // Schema->TryCreateConnection(TriggeredSecondsInitialize->GetValuePin(), ComboActionEvent->FindPinChecked(TEXT("TriggeredTime"))); - - // UK2Node_AssignmentStatement* InputActionInitialize = CompilerContext.SpawnIntermediateNode(this, SourceGraph); - // InputActionInitialize->AllocateDefaultPins(); - // Schema->TryCreateConnection(InputActionVar->GetVariablePin(), InputActionInitialize->GetVariablePin()); - // Schema->TryCreateConnection(InputActionInitialize->GetValuePin(), ComboActionEvent->FindPinChecked(TEXT("SourceAction"))); - // - // // Connect the assign location to the assign elapsed time nodes - // Schema->TryCreateConnection(ActionValueInitialize->GetThenPin(), ElapsedSecondsInitialize->GetExecPin()); - // Schema->TryCreateConnection(ElapsedSecondsInitialize->GetThenPin(), TriggeredSecondsInitialize->GetExecPin()); - // Schema->TryCreateConnection(TriggeredSecondsInitialize->GetThenPin(), InputActionInitialize->GetExecPin()); - // - // // Move the original event connections to the then pin of the Input Action assign - // CompilerContext.MovePinLinksToIntermediate(*EachPin, *InputActionInitialize->GetThenPin()); - - // // Move the original event variable connections to the intermediate nodes - // CompilerContext.MovePinLinksToIntermediate(*FindPin(ActionValuePinName), *ActionValueVar->GetVariablePin()); - // CompilerContext.MovePinLinksToIntermediate(*FindPin(ElapsedSecondsPinName), *ElapsedSecondsVar->GetVariablePin()); - // CompilerContext.MovePinLinksToIntermediate(*FindPin(TriggeredSecondsPinName), *TriggeredSecondsVar->GetVariablePin()); - // CompilerContext.MovePinLinksToIntermediate(*FindPin(InputActionPinName), *InputActionVar->GetVariablePin()); - //} + if (!ComboActionEvent) + { + continue; + } + } } void UK2Node_ComboAction::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const diff --git a/Source/ComboInput/Private/Events/K2Node_ComboActionEvent.cpp b/Source/ComboInput/Private/Events/K2Node_ComboActionEvent.cpp index e77fbb7..666f0d7 100644 --- a/Source/ComboInput/Private/Events/K2Node_ComboActionEvent.cpp +++ b/Source/ComboInput/Private/Events/K2Node_ComboActionEvent.cpp @@ -2,6 +2,7 @@ #include "Events/K2Node_ComboActionEvent.h" +#include "ComboInputTriggers.h" #include "Events/ComboActionDelegateBinding.h" #include UE_INLINE_GENERATED_CPP_BY_NAME(K2Node_ComboActionEvent) @@ -11,7 +12,7 @@ UK2Node_ComboActionEvent::UK2Node_ComboActionEvent(const FObjectInitializer &Obj : Super(ObjectInitializer) { bInternalEvent = true; - //TriggerEvent = ETriggerEvent::None; + TriggerEvent = EComboActionTriggerEvent::None; } UClass *UK2Node_ComboActionEvent::GetDynamicBindingClass() const @@ -24,9 +25,8 @@ void UK2Node_ComboActionEvent::RegisterDynamicBinding(UDynamicBlueprintBinding * UComboActionDelegateBinding *ComboActionBindingObject = CastChecked(BindingObject); FBlueprintComboActionBinding Binding; - Binding.InputAction = this->ComboAction; - //Binding.TriggerEvent = this->TriggerEvent; Binding.FunctionNameToBind = this->CustomFunctionName; + Binding.TriggerEvent = this->TriggerEvent; ComboActionBindingObject->ComboActionDelegateBindings.Add(Binding); } diff --git a/Source/ComboInput/Private/Events/K2Node_ComboActionEvent.h b/Source/ComboInput/Private/Events/K2Node_ComboActionEvent.h index 34e080a..cf48ad5 100644 --- a/Source/ComboInput/Private/Events/K2Node_ComboActionEvent.h +++ b/Source/ComboInput/Private/Events/K2Node_ComboActionEvent.h @@ -22,8 +22,8 @@ public: UPROPERTY() TObjectPtr ComboAction; - //UPROPERTY() - // ETriggerEvent TriggerEvent; + UPROPERTY() + EComboActionTriggerEvent TriggerEvent; //~ Begin UK2Node Interface virtual UClass *GetDynamicBindingClass() const override; diff --git a/Source/ComboInput/Public/ComboInputTriggers.h b/Source/ComboInput/Public/ComboInputTriggers.h new file mode 100644 index 0000000..89541ec --- /dev/null +++ b/Source/ComboInput/Public/ComboInputTriggers.h @@ -0,0 +1,16 @@ +// ©2022 Batty Bovine Productions, LLC. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "ComboInputTriggers.generated.h" + + +UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true")) +enum class EComboActionTriggerEvent : uint8 +{ + None = (0x0) UMETA(Hidden), + Activated = (1 << 0), + Released = (1 << 1), +}; +ENUM_CLASS_FLAGS(EComboActionTriggerEvent) diff --git a/Source/ComboInput/Public/Components/ComboManagerComponent.h b/Source/ComboInput/Public/Components/ComboManagerComponent.h index b2d1df7..8012efc 100644 --- a/Source/ComboInput/Public/Components/ComboManagerComponent.h +++ b/Source/ComboInput/Public/Components/ComboManagerComponent.h @@ -5,12 +5,15 @@ #include "CoreMinimal.h" #include "Components/ActorComponent.h" -#include "Engine/DataAsset.h" +#include "ComboInputAssets.h" +#include "Events/ComboActionDelegateBinding.h" #include "ComboManagerComponent.generated.h" DECLARE_LOG_CATEGORY_EXTERN(LogComboManagerComponent, Log, All); +DECLARE_DYNAMIC_DELEGATE/*_OneParam*/(FComboActionHandlerDynamicSignature/*, EComboActionTriggerEvent, TriggerEvent*/); + UCLASS(BlueprintType, ClassGroup=(Input), meta=(BlueprintSpawnableComponent)) class COMBOINPUT_API UComboManagerComponent : public UActorComponent @@ -24,6 +27,13 @@ public: UFUNCTION(BlueprintCallable) void ActivateComboInput(const class UComboInputAsset *Input); + void BindAction(UObject *ObjectToBindTo, FName FunctionName) + { + FComboActionHandlerDynamicSignature Delegate; + Delegate.BindUFunction(ObjectToBindTo, FunctionName); + this->ComboActionEventBindings.Add(MoveTemp(Delegate)); + } + protected: UPROPERTY(BlueprintReadOnly, EditDefaultsOnly) TObjectPtr DefaultStartNode; @@ -47,6 +57,8 @@ private: const class UComboSequenceNode *ActiveNode = nullptr; const class UComboSequenceNode *PreviousNode = nullptr; + TArray ComboActionEventBindings; + TObjectPtr AttachedInputBuffer; FTimerHandle FinishTransitionTimer; diff --git a/Source/ComboInput/Public/Events/ComboActionDelegateBinding.h b/Source/ComboInput/Public/Events/ComboActionDelegateBinding.h index ab43623..a26126b 100644 --- a/Source/ComboInput/Public/Events/ComboActionDelegateBinding.h +++ b/Source/ComboInput/Public/Events/ComboActionDelegateBinding.h @@ -2,8 +2,8 @@ #pragma once -#include "Engine/DynamicBlueprintBinding.h" -#include "InputTriggers.h" +#include "Engine/InputDelegateBinding.h" +#include "ComboInputTriggers.h" #include "ComboActionDelegateBinding.generated.h" @@ -14,9 +14,8 @@ struct COMBOINPUT_API FBlueprintComboActionBinding GENERATED_BODY() public: - UPROPERTY() TObjectPtr InputAction = nullptr; - //UPROPERTY() ETriggerEvent TriggerEvent = ETriggerEvent::None; UPROPERTY() FName FunctionNameToBind = NAME_None; + UPROPERTY() EComboActionTriggerEvent TriggerEvent = EComboActionTriggerEvent::None; }; UCLASS() @@ -26,7 +25,10 @@ class COMBOINPUT_API UComboActionDelegateBinding : public UDynamicBlueprintBindi public: UComboActionDelegateBinding(const FObjectInitializer &ObjectInitializer); - void BindToComboManagerComponent(class UComboManagerComponent *ComboManager, class UObject *ObjectToBindTo) const; + + //~ Begin UDynamicBlueprintBinding Interface + virtual void BindDynamicDelegates(UObject *InInstance) const override; + //~ End UDynamicBlueprintBinding Interface UPROPERTY() TArray ComboActionDelegateBindings; }; diff --git a/Source/ComboInput/Public/Events/K2Node_ComboAction.h b/Source/ComboInput/Public/Events/K2Node_ComboAction.h index 7f8bf37..6b85c2a 100644 --- a/Source/ComboInput/Public/Events/K2Node_ComboAction.h +++ b/Source/ComboInput/Public/Events/K2Node_ComboAction.h @@ -47,8 +47,6 @@ public: virtual FText GetMenuCategory() const override; virtual bool CanUserEditPinAdvancedViewFlag() const override { return true; } virtual FBlueprintNodeSignature GetSignature() const override; - virtual void PostReconstructNode(); - virtual void PinConnectionListChanged(UEdGraphPin *Pin); //~ End UK2Node Interface //~ Begin IK2Node_EventNodeInterface Interface. @@ -57,7 +55,6 @@ public: private: FName GetActionName() const; - void HideEventPins(UEdGraphPin *RetainPin); /** Constructing FText strings can be costly, so we cache the node's title/tooltip */ FNodeTextCache CachedTooltip; diff --git a/Source/ComboInputEditor/ComboInputEditor.build.cs b/Source/ComboInputEditor/ComboInputEditor.build.cs index 899e3c8..e333f4c 100644 --- a/Source/ComboInputEditor/ComboInputEditor.build.cs +++ b/Source/ComboInputEditor/ComboInputEditor.build.cs @@ -26,6 +26,7 @@ public class ComboInputEditor : ModuleRules "Core", "CoreUObject", "AssetTools", + "SlateCore" } ); diff --git a/Source/ComboInputEditor/Private/ComboInputEditor.cpp b/Source/ComboInputEditor/Private/ComboInputEditor.cpp index 1629e00..360acff 100644 --- a/Source/ComboInputEditor/Private/ComboInputEditor.cpp +++ b/Source/ComboInputEditor/Private/ComboInputEditor.cpp @@ -4,8 +4,12 @@ #include "ComboInputAssets.h" #include "ToolMenuSection.h" + #include "AssetTypeActions/AssetTypeActions_DataAsset.h" #include "Interfaces/IPluginManager.h" +#include "Styling/SlateStyle.h" +#include "Styling/SlateStyleMacros.h" +#include "Styling/SlateStyleRegistry.h" #include UE_INLINE_GENERATED_CPP_BY_NAME(ComboInputEditor) @@ -113,15 +117,49 @@ UObject *UComboInputAsset_Factory::FactoryCreateNew(UClass *Class, UObject *InPa +class FComboInputSlateStyle final : public FSlateStyleSet +{ +public: + FComboInputSlateStyle() : FSlateStyleSet("ComboInputEditor") + { + SetParentStyleName(FAppStyle::GetAppStyleSetName()); + + // The icons are located in /Engine/Plugins/ComboInput/Content/Editor/Slate/Icons + SetContentRoot(FPaths::EnginePluginsDir() / TEXT("ComboInput/Content/Editor/Slate")); + SetCoreContentRoot(FPaths::EngineContentDir() / TEXT("Slate")); + + // Combo Input Editor icons + static const FVector2D Icon16 = FVector2D(16.0f, 16.0f); + static const FVector2D Icon64 = FVector2D(64.0f, 64.0f); + + Set("ComboInputIcon_Small", new IMAGE_BRUSH_SVG("Icons/ComboInput_16", Icon16)); + Set("ComboInputIcon_Large", new IMAGE_BRUSH_SVG("Icons/ComboInput_64", Icon64)); + + Set("ClassIcon.ComboAction", new IMAGE_BRUSH_SVG("Icons/ComboAction_16", Icon16)); + Set("ClassThumbnail.ComboAction", new IMAGE_BRUSH_SVG("Icons/ComboAction_64", Icon64)); + + Set("ClassIcon.ComboSequenceNode", new IMAGE_BRUSH_SVG("Icons/ComboSequenceNode_16", Icon16)); + Set("ClassThumbnail.ComboSequenceNode", new IMAGE_BRUSH_SVG("Icons/ComboSequenceNode_64", Icon64)); + + Set("ClassIcon.ComboInputAsset", new IMAGE_BRUSH_SVG("Icons/ComboInputAsset_16", Icon16)); + Set("ClassThumbnail.ComboInputAsset", new IMAGE_BRUSH_SVG("Icons/ComboInputAsset_64", Icon64)); + } +}; + + + void FComboInputEditorModule::StartupModule() { // Register combo action asset IAssetTools &AssetTools = FModuleManager::LoadModuleChecked("AssetTools").Get(); FComboInputEditorModule::ComboAssetsCategory = AssetTools.RegisterAdvancedAssetCategory(FName(TEXT("Input")), LOCTEXT("InputAssetsCategory", "Input")); - this->RegisterAssetTypeActions(AssetTools, MakeShareable(new FAssetTypeActions_ComboAction)); this->RegisterAssetTypeActions(AssetTools, MakeShareable(new FAssetTypeActions_ComboSequenceNode)); this->RegisterAssetTypeActions(AssetTools, MakeShareable(new FAssetTypeActions_ComboInputAsset)); + + // Make a new style set for Combo Input, which will register any custom icons for the types in this plugin + StyleSet = MakeShared(); + FSlateStyleRegistry::RegisterSlateStyle(*StyleSet.Get()); } void FComboInputEditorModule::ShutdownModule() diff --git a/Source/ComboInputEditor/Public/ComboInputEditor.h b/Source/ComboInputEditor/Public/ComboInputEditor.h index b309eb4..0f3c00d 100644 --- a/Source/ComboInputEditor/Public/ComboInputEditor.h +++ b/Source/ComboInputEditor/Public/ComboInputEditor.h @@ -77,4 +77,6 @@ private: static EAssetTypeCategories::Type ComboAssetsCategory; TArray> CreatedAssetTypeActions; + + TSharedPtr StyleSet; };