Initial commit.

This commit is contained in:
Jamie Greunbaum 2023-09-09 17:28:41 -04:00
commit 2e5aae7f67
15 changed files with 864 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
Binaries/
Intermediate/

32
ComboInput.uplugin Normal file
View File

@ -0,0 +1,32 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "0.1.0.0",
"FriendlyName": "Combo Input",
"Description": "A set of components and classes for capturing Enhanced Input actions for buffering actions and stringing them into complex combos.",
"Category": "Input",
"CreatedBy": "Jamie Greunbaum",
"EngineVersion": "5.2.0",
"CanContainContent": true,
"IsBetaVersion": true,
"IsExperimentalVersion": true,
"Installed": true,
"Modules": [
{
"Name": "ComboInput",
"Type": "Runtime",
"LoadingPhase": "PreDefault"
},
{
"Name": "ComboInputEditor",
"Type": "Editor",
"LoadingPhase": "Default"
}
],
"Plugins": [
{
"Name": "EnhancedInput",
"Enabled": true
}
]
}

BIN
Resources/Icon128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,74 @@
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class ComboInput : ModuleRules
{
public ComboInput(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
bLegacyPublicIncludePaths = false;
ShadowVariableWarningLevel = WarningLevel.Error;
PublicIncludePaths.AddRange
(
new string[]
{
// ... add public include paths required here ...
}
);
PrivateIncludePaths.AddRange
(
new string[]
{
"ComboInput/Private"
}
);
PublicDependencyModuleNames.AddRange
(
new string[]
{
"Core",
"CoreUObject",
"Engine",
"UMG",
"EnhancedInput",
// ... add other public dependencies that you statically link with here ...
}
);
PrivateDependencyModuleNames.AddRange
(
new string[]
{
"Engine",
"Slate",
"SlateCore",
"GameplayTags",
"DeveloperSettings",
"UMG",
"Projects"
// ... add private dependencies that you statically link with here ...
}
);
if (Target.bBuildEditor)
{
PrivateDependencyModuleNames.Add("UnrealEd");
}
DynamicallyLoadedModuleNames.AddRange
(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
}
}

View File

@ -0,0 +1,24 @@
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
#include "ComboInput.h"
#include "GameplayTagsManager.h"
#include "Interfaces/IPluginManager.h"
#define LOCTEXT_NAMESPACE "FComboInputModule"
void FComboInputModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}
void FComboInputModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FComboInputModule, ComboInput)

View File

@ -0,0 +1,97 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#include "Components/ComboManagerComponent.h"
#include "Components/InputBufferComponent.h"
#include "Interfaces/ComboHandlerInterface.h"
DEFINE_LOG_CATEGORY(LogComboManagerComponent);
UComboManagerComponent::UComboManagerComponent()
{
PrimaryComponentTick.bStartWithTickEnabled = false;
PrimaryComponentTick.bTickEvenWhenPaused = false;
PrimaryComponentTick.bCanEverTick = false;
}
void UComboManagerComponent::BeginPlay()
{
Super::BeginPlay();
const AActor *OwningActor = this->GetOwner();
if (const IComboHandlerInterface *ComboHandler = Cast<IComboHandlerInterface>(OwningActor))
{
if (UInputBufferComponent *InputBuffer = IComboHandlerInterface::Execute_GetInputBuffer(OwningActor))
{
this->AttachedInputBuffer = InputBuffer;
this->AttachedInputBuffer->NewComboInput.BindUObject(this, &UComboManagerComponent::ComboInputReceived);
}
}
}
void UComboManagerComponent::ComboInputReceived(const UComboInputAsset *Input)
{
/************ DEBUG ************/
for (const TPair<TObjectPtr<const UComboInputAsset>, float> &Pair : this->DEBUG__UnlockTimers)
{
if (!this->DEBUG__TimerHandles.Contains(Pair.Key))
{
this->DEBUG__TimerHandles.Add(Pair.Key);
}
this->GetWorld()->GetTimerManager().ClearTimer(this->DEBUG__TimerHandles[Pair.Key]);
this->GetWorld()->GetTimerManager().SetTimer(this->DEBUG__TimerHandles[Pair.Key], FTimerDelegate::CreateUObject(this, &UComboManagerComponent::DEBUG__UnlockAction, Pair.Key), Pair.Value, false);
}
/********** END DEBUG **********/
// If we received an offset input, perform the offset here and then leave.
if (Input == this->OffsetInput)
{
this->ActiveNode = this->PreviousNode;
this->GetWorld()->GetTimerManager().ClearTimer(this->FinishTransitionTimer);
UE_LOG(LogComboManagerComponent, Verbose, TEXT("Combo has been offset by %s"), *Input->ComboInputName.ToString());
return;
}
const TObjectPtr<const UComboSequenceNode> CurrentNode = (this->ActiveNode ? this->ActiveNode : this->DefaultStartNode);
checkf(CurrentNode, TEXT("No combo sequence nodes available."));
if (CurrentNode->ComboBranch.Contains(Input))
{
const FComboSequenceAction &ActionData = CurrentNode->ComboBranch[Input];
if (ActionData.ComboAction)
{
this->BeginNodeTransition(ActionData.NextNode);
UE_LOG(LogComboManagerComponent, Verbose, TEXT("%s activated"), *ActionData.ComboAction->ActionName.ToString());
}
}
else
{
UE_LOG(LogComboManagerComponent, Verbose, TEXT("No branch found for this action"));
}
}
void UComboManagerComponent::DEBUG__UnlockAction(TObjectPtr<const UComboInputAsset> Unlock)
{
this->AttachedInputBuffer->UnlockComboInput(Unlock);
}
void UComboManagerComponent::BeginNodeTransition(const UComboSequenceNode *NextNode)
{
this->PreviousNode = this->ActiveNode;
this->ActiveNode = NextNode;
this->GetWorld()->GetTimerManager().SetTimer(this->FinishTransitionTimer, this, &UComboManagerComponent::FinishTransition, 0.5f);
this->GetWorld()->GetTimerManager().SetTimer(this->DEBUG__ResetComboTimer, this, &UComboManagerComponent::DEBUG__ResetCombo, 1.0f);
}
void UComboManagerComponent::DEBUG__ResetCombo()
{
this->ActiveNode = this->PreviousNode = nullptr;
}
void UComboManagerComponent::FinishTransition()
{
this->PreviousNode = this->ActiveNode;
}

View File

@ -0,0 +1,191 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#include "Components/InputBufferComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/PlayerController.h"
DEFINE_LOG_CATEGORY(LogInputBufferComponent);
UInputBufferComponent::UInputBufferComponent()
{
PrimaryComponentTick.bStartWithTickEnabled = false;
PrimaryComponentTick.bTickEvenWhenPaused = false;
PrimaryComponentTick.bCanEverTick = false;
}
void UInputBufferComponent::BeginPlay()
{
Super::BeginPlay();
// Get all unique EnhancedInput actions bound to combo input actions.
TSet<const UInputAction*> InputActionsToBind;
for (const UComboInputAsset *ComboInput : this->ComboActions)
{
for (const UInputAction *InputAction : ComboInput->ActionGroup)
{
InputActionsToBind.Add(InputAction);
}
}
APlayerController *Controller = Cast<APlayerController>(this->GetOwner());
checkf(Controller, TEXT("No player controller found as owner of %s"), *this->GetName());
if (this->EnhancedInputComponent = Cast<UEnhancedInputComponent>(Controller->InputComponent))
{
// Bind the input actions we found to the buffer management functions.
for (const UInputAction *InputAction : InputActionsToBind)
{
this->EnhancedInputComponent->BindAction(InputAction, ETriggerEvent::Started, this, &UInputBufferComponent::AddActionToBuffer, InputAction);
this->EnhancedInputComponent->BindAction(InputAction, ETriggerEvent::Completed, this, &UInputBufferComponent::ExpireAction, InputAction);
}
}
else
{
UE_LOG(LogInputBufferComponent, Error, TEXT("Parent of %s is not a UEnhancedInputComponent type."), *this->GetName());
}
}
void UInputBufferComponent::AddActionToBuffer(const FInputActionValue &Value, const class UInputAction *Action)
{
this->MostRecentActions.Add(Action);
this->ExpiringActions.Remove(Action);
// Find any combo input that matches this action, plus buffered actions.
for (const UComboInputAsset *Combo : this->ComboActions)
{
if (Combo->MatchesInputActions(this->MostRecentActions))
{
this->ActivateComboInput(Combo);
break;
}
}
this->GetWorld()->GetTimerManager().SetTimer(this->MultiPressTimerHandle, this, &UInputBufferComponent::ClearMultiPresses, this->MultiPressTimerLength);
}
void UInputBufferComponent::ClearMultiPresses()
{
#if WITH_EDITOR
TArray<FString> ActionNames;
for (const UInputAction *Action : this->MostRecentActions)
{
ActionNames.Add(Action->GetName());
}
UE_LOG(LogInputBufferComponent, Verbose, TEXT("Multi-press buffer cleared (%s)"), *FString::Join(ActionNames, TEXT(" | ")));
#endif
this->MostRecentActions.Empty();
}
void UInputBufferComponent::ActivateComboInput(const UComboInputAsset *ComboInput)
{
checkf(ComboInput, TEXT("Invalid UComboInputAsset"));
// Make this combo input active if it isn't being locked, or if we are
// overwriting a previous combo input with a multi-press combo input.
const bool bMultiPressTimerActive = this->GetWorld()->GetTimerManager().IsTimerActive(this->MultiPressTimerHandle);
const bool bComboInputLocked = this->LockedComboInputs.Contains(ComboInput);
if (bMultiPressTimerActive || !bComboInputLocked)
{
if (!ComboInput->LockedComboInputs.IsEmpty())
{
// Set the combo input as active, and copy its lock data.
this->InputBufferActive = ComboInput;
this->LockedComboInputs = ComboInput->LockedComboInputs;
// Make sure the hold is clear if we're coming off of a multi-press action.
if (bMultiPressTimerActive)
{
this->InputBufferHold = nullptr;
}
//this->GetWorld()->GetTimerManager().SetTimer(this->ForceUnlockTimerHandle, this, &UInputBufferComponent::ForceUnlockComboInputs, this->ForceUnlockTimerLength);
UE_LOG(LogInputBufferComponent, Verbose, TEXT("%s is active."), *ComboInput->ComboInputName.ToString());
}
else
{
UE_LOG(LogInputBufferComponent, Verbose, TEXT("%s is active and won't lock inputs."), *ComboInput->ComboInputName.ToString());
}
this->NewComboInput.Execute(ComboInput);
}
else
{
this->InputBufferHold = ComboInput;
if (bComboInputLocked)
{
UE_LOG(LogInputBufferComponent, Verbose, TEXT("%s is locked and won't be activated yet."), *ComboInput->ComboInputName.ToString());
}
else
{
UE_LOG(LogInputBufferComponent, Verbose, TEXT("%s added to buffer."), *ComboInput->ComboInputName.ToString());
}
}
}
void UInputBufferComponent::UnlockComboInput(const UComboInputAsset *Unlocked)
{
// Remove the newly-unlocked asset from the locked combo inputs.
UE_CLOG(this->LockedComboInputs.Contains(Unlocked), LogInputBufferComponent, Verbose, TEXT("%s has unlocked."), *Unlocked->ComboInputName.ToString());
this->LockedComboInputs.Remove(Unlocked);
// Check if the newly unlocked combo input is in the hold.
if (Unlocked == this->InputBufferHold)
{
const UComboInputAsset *OriginalActive = this->InputBufferActive;
// Activate the held combo input.
const UComboInputAsset *HeldAsset = this->InputBufferHold;
this->InputBufferHold = nullptr;
if (HeldAsset)
{
this->ActivateComboInput(HeldAsset);
}
UE_LOG(LogInputBufferComponent, Verbose, TEXT("%s has expired."), *OriginalActive->ComboInputName.ToString());
}
}
void UInputBufferComponent::ExpireAction(const FInputActionValue &Value, const class UInputAction *Action)
{
this->ExpiringActions.Add(Action);
this->GetWorld()->GetTimerManager().SetTimer(this->InputReleaseExpirationTimerHandle, this, &UInputBufferComponent::ExpireBufferedActions, this->InputReleaseExpirationTimerLength);
}
void UInputBufferComponent::ExpireBufferedActions()
{
// Only bother dealing with this if there's something to deal with in the first place.
if (!this->ExpiringActions.IsEmpty())
{
UE_SUPPRESS(LogInputBufferComponent, Verbose,
{
TArray<FString> ActionNames;
for (const UInputAction *Action : this->ExpiringActions)
{
ActionNames.Add(Action->GetName());
}
UE_LOG(LogInputBufferComponent, Verbose, TEXT("Released actions expired (%s)"), *FString::Join(ActionNames, TEXT(" | ")));
}
);
// If there is an action in the hold, check if it's related
// to our current released buttons, and if so cancel it.
if (this->InputBufferHold)
{
for (const UInputAction *Action : this->ExpiringActions)
{
if (this->InputBufferHold->MatchesInputAction(Action))
{
UE_LOG(LogInputBufferComponent, Verbose, TEXT("%s has been cancelled."), *this->InputBufferHold->ComboInputName.ToString());
this->InputBufferHold = nullptr;
break;
}
}
}
this->ExpiringActions.Empty();
}
}

View File

@ -0,0 +1,17 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#include "Interfaces/ComboHandlerInterface.h"
#include "Components/ComboManagerComponent.h"
#include "Components/InputBufferComponent.h"
UInputBufferComponent *IComboHandlerInterface::GetInputBuffer_Implementation() const
{
return nullptr;
}
UComboManagerComponent *IComboHandlerInterface::GetComboManager_Implementation() const
{
return nullptr;
}

View File

@ -0,0 +1,37 @@
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
class FComboInputModule : public IModuleInterface
{
public:
/**
* Singleton-like access to this module's interface. This is just for convenience!
* Beware of calling this during the shutdown phase, though. Your module might have been unloaded already.
*
* @return Returns singleton instance, loading the module on demand if needed
*/
static FComboInputModule &Get()
{
return FModuleManager::LoadModuleChecked<FComboInputModule>("ComboInput");
}
/**
* Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true.
*
* @return True if the module is loaded and ready to use
*/
static bool IsAvailable()
{
return FModuleManager::Get().IsModuleLoaded("ComboInput");
}
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};

View File

@ -0,0 +1,90 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Engine/DataAsset.h"
#include "ComboManagerComponent.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(LogComboManagerComponent, Log, All);
USTRUCT(BlueprintType)
struct COMBOINPUT_API FComboSequenceAction
{
GENERATED_BODY()
public:
// Action to perform when the associated combo sequence node is activated.
UPROPERTY(BlueprintReadOnly, EditAnywhere)
TObjectPtr<const class UComboAction> ComboAction;
// Sequence node to switch to once this action is complete.
UPROPERTY(BlueprintReadOnly, EditAnywhere)
TObjectPtr<const class UComboSequenceNode> NextNode;
};
UCLASS(BlueprintType)
class COMBOINPUT_API UComboAction : public UDataAsset
{
GENERATED_BODY()
public:
// Human-readable name of this combo action.
UPROPERTY(BlueprintReadOnly, EditAnywhere)
FName ActionName;
};
UCLASS(BlueprintType)
class COMBOINPUT_API UComboSequenceNode : public UDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, EditAnywhere)
TMap<const class UComboInputAsset*, struct FComboSequenceAction> ComboBranch;
};
UCLASS(BlueprintType, ClassGroup=(Input), meta=(BlueprintSpawnableComponent))
class COMBOINPUT_API UComboManagerComponent : public UActorComponent
{
GENERATED_BODY()
public:
UComboManagerComponent();
virtual void BeginPlay() override;
protected:
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
TObjectPtr<const class UComboSequenceNode> DefaultStartNode;
// This input will be recognised as an offset input, which cancels a node transition
// if activated early enough in the transition. This locks the current place in the
// combo and allows this combo string to be continued after this input has executed.
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
TObjectPtr<const class UComboInputAsset> OffsetInput;
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
TMap<TObjectPtr<const class UComboInputAsset>, float> DEBUG__UnlockTimers;
private:
void ComboInputReceived(const class UComboInputAsset *Input);
void BeginNodeTransition(const class UComboSequenceNode *NextNode);
void FinishTransition();
void DEBUG__UnlockAction(TObjectPtr<const class UComboInputAsset> Unlock);
void DEBUG__ResetCombo();
const class UComboSequenceNode *ActiveNode = nullptr;
const class UComboSequenceNode *PreviousNode = nullptr;
TObjectPtr<class UInputBufferComponent> AttachedInputBuffer;
FTimerHandle FinishTransitionTimer;
FTimerHandle DEBUG__ResetComboTimer;
TMap<TObjectPtr<const class UComboInputAsset>, FTimerHandle> DEBUG__TimerHandles;
};

View File

@ -0,0 +1,122 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "EnhancedInputComponent.h"
#include "Components/ActorComponent.h"
#include "InputBufferComponent.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(LogInputBufferComponent, Log, All);
UCLASS(BlueprintType)
class COMBOINPUT_API UComboInputAsset : public UDataAsset
{
GENERATED_BODY()
public:
bool MatchesInputAction(const class UInputAction* Action) const
{
if (this->ActionGroup.Num() == 1 && this->ActionGroup.Contains(Action))
{
return true;
}
return false;
}
bool MatchesInputActions(TSet<const class UInputAction *> Actions) const
{
if (this->ActionGroup.Num() == Actions.Num())
{
for (const UInputAction *Action : Actions)
{
if (!this->ActionGroup.Contains(Action))
{
return false;
}
}
return true;
}
return false;
}
// Human-readable name of this combo input.
UPROPERTY(BlueprintReadWrite, EditAnywhere)
FName ComboInputName;
// Combined actions that add up to this combo input when activated
// within a short time of one another. If only one is present, then
// this combo input asset will simply represent that action.
UPROPERTY(BlueprintReadWrite, EditAnywhere)
TSet<TObjectPtr<const class UInputAction>> ActionGroup;
// Combo inputs that should be prevented from occurring during this
// action. These will be locked when the action is broadcast, and
// should be unlocked by the receiving actor by sending an unlock
// event.
UPROPERTY(BlueprintReadWrite, EditAnywhere)
TSet<TObjectPtr<const class UComboInputAsset>> LockedComboInputs;
};
UCLASS(BlueprintType, ClassGroup=(Input), meta=(BlueprintSpawnableComponent))
class COMBOINPUT_API UInputBufferComponent : public UActorComponent
{
GENERATED_BODY()
public:
UInputBufferComponent();
virtual void BeginPlay() override;
UFUNCTION(BlueprintCallable)
void UnlockComboInput(const class UComboInputAsset *Unlocked);
// List of possible combo inputs that can be taken. A combo input is selected from this list
// either if an action is made while the current combo is inactive, or when the previous
// action expires.
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
TSet<const class UComboInputAsset*> ComboActions;
// Length of time after releasing an input to keep the associated combo action buffered before clearing it.
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, meta=(UIMin="0.0", UIMax="0.5"))
float InputReleaseExpirationTimerLength = 0.0666666666666666667f;
// Length of time within which we can recognise multiple button presses as one input.
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, meta=(UIMin="0.02", UIMax="0.25"))
float MultiPressTimerLength = 0.025f;
// Lenght of time before forcibly unlocking any locked combo inputs.
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, meta=(UIMin="1.0", UIMax="10.0"))
float ForceUnlockTimerLength = 5.0f;
DECLARE_DELEGATE_OneParam(FNewComboInput, const class UComboInputAsset*);
FNewComboInput NewComboInput;
private:
void AddActionToBuffer(const FInputActionValue &Value, const class UInputAction *Action);
void ExpireAction(const FInputActionValue &Value, const class UInputAction *Action);
void ActivateComboInput(const class UComboInputAsset *ComboInput);
void ClearMultiPresses();
void ExpireBufferedActions();
TObjectPtr<class UEnhancedInputComponent> EnhancedInputComponent;
// Currently active combo input.
TObjectPtr<const class UComboInputAsset> InputBufferActive;
// Combo input held until the current input has expired.
TObjectPtr<const class UComboInputAsset> InputBufferHold;
// Set of currently locked actions; will not be activated until an unlock signal is received.
TSet<TObjectPtr<const class UComboInputAsset>> LockedComboInputs;
TSet<const class UInputAction*> MostRecentActions;
TSet<const class UInputAction*> ExpiringActions;
FTimerHandle MultiPressTimerHandle;
FTimerHandle InputReleaseExpirationTimerHandle;
FTimerHandle ForceUnlockTimerHandle;
};

View File

@ -0,0 +1,32 @@
// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "ComboHandlerInterface.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI, meta=(Blueprintable))
class UComboHandlerInterface : public UInterface
{
GENERATED_BODY()
};
/**
* Interface for anything that handles combo inputs and contains a
* UComboManagerComponent.
*/
class COMBOINPUT_API IComboHandlerInterface
{
GENERATED_BODY()
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
class UInputBufferComponent *GetInputBuffer() const;
virtual class UInputBufferComponent *GetInputBuffer_Implementation() const;
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
class UComboManagerComponent *GetComboManager() const;
virtual class UComboManagerComponent *GetComboManager_Implementation() const;
};

View File

@ -0,0 +1,53 @@
using UnrealBuildTool;
public class ComboInputEditor : ModuleRules
{
public ComboInputEditor(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
bLegacyPublicIncludePaths = false;
ShadowVariableWarningLevel = WarningLevel.Error;
PrecompileForTargets = PrecompileTargetsType.None;
bPrecompile = false;
bUsePrecompiled = false;
PublicDependencyModuleNames.AddRange
(new string[]
{
"Core",
"CoreUObject",
"Engine",
"UnrealEd",
"AssetTools"
}
);
PrivateDependencyModuleNames.AddRange
(
new string[]
{
"ComboInput",
"AssetTools",
"Slate",
"SlateCore",
"GraphEditor",
"PropertyEditor",
"EditorStyle",
"Kismet",
"KismetWidgets",
"ApplicationCore",
"ToolMenus",
"DeveloperSettings",
"Projects",
"BlueprintGraph",
"InputCore",
"MainFrame"
// ... add private dependencies that you statically link with here ...
}
);
}
}

View File

@ -0,0 +1,23 @@
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
#include "ComboInputEditor.h"
#include "Interfaces/IPluginManager.h"
#define LOCTEXT_NAMESPACE "FComboInputEditorModule"
void FComboInputEditorModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
}
void FComboInputEditorModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FComboInputEditorModule, ComboInputEditorModule)

View File

@ -0,0 +1,70 @@
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "Modules/ModuleManager.h"
#include "EdGraphUtilities.h"
#include "IAssetTools.h"
// #include "Interfaces/IHttpRequest.h"
// class FHttpModule;
// class FSlateStyleSet;
class FComboInputEditorModule : public IModuleInterface
{
public:
/**
* Singleton-like access to this module's interface. This is just for convenience!
* Beware of calling this during the shutdown phase, though. Your module might have been unloaded already.
*
* @return Returns singleton instance, loading the module on demand if needed
*/
static FComboInputEditorModule &Get()
{
return FModuleManager::LoadModuleChecked<FComboInputEditorModule>( "ComboInputEditor" );
}
/**
* Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true.
*
* @return True if the module is loaded and ready to use
*/
static bool IsAvailable()
{
return FModuleManager::Get().IsModuleLoaded("ComboInputEditor");
}
/* Called when the module is loaded */
virtual void StartupModule() override;
/* Called when the module is unloaded */
virtual void ShutdownModule() override;
private:
// void RegisterAssetTypeAction(IAssetTools& AssetTools, TSharedRef<IAssetTypeActions> Action);
// void OnGetResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);
// UFUNCTION() void SendHTTPGet();
// void PluginButtonClicked();
// void RegisterMenus();
private:
// TSharedPtr<class FUICommandList> PluginCommands;
// TSharedPtr<FSlateStyleSet> DialogueTreeSet;
// TSharedPtr<class FMounteaDialogueGraphAssetAction> MounteaDialogueGraphAssetActions;
// TSharedPtr<class FMounteaDialogueAdditionalDataAssetAction> MounteaDialogueAdditionalDataAssetActions;
// TSharedPtr<class FMounteaDialogueDecoratorAssetAction> MounteaDialogueDecoratorAssetAction;
// TSharedPtr<struct FGraphPanelNodeFactory> GraphPanelNodeFactory_MounteaDialogueGraph;
// TArray< TSharedPtr<IAssetTypeActions> > CreatedAssetTypeActions;
// EAssetTypeCategories::Type MounteaDialogueGraphAssetCategoryBit;
// FHttpModule* Http;
// TArray<FName> RegisteredCustomClassLayouts;
// TArray<FName> RegisteredCustomPropertyTypeLayout;
};