313 lines
15 KiB
C++
313 lines
15 KiB
C++
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
|
|
|
#include "ComboInputEditor.h"
|
|
|
|
#include "ComboActionGraph.h"
|
|
#include "ComboInputAssets.h"
|
|
#include "ToolMenuSection.h"
|
|
|
|
#include "AssetTypeActions/AssetTypeActions_DataAsset.h"
|
|
#include "Ed/AssetEditor_ComboActionGraph.h"
|
|
#include "Ed/EdComboActionGraphEdge.h"
|
|
#include "Ed/EdComboActionGraphNode.h"
|
|
#include "Ed/FComboActionGraphEditorCommands.h"
|
|
#include "Ed/SEdComboActionGraphEdge.h"
|
|
#include "Ed/SEdComboActionGraphNode.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)
|
|
|
|
#define LOCTEXT_NAMESPACE "FComboInputEditorModule"
|
|
|
|
EAssetTypeCategories::Type FComboInputEditorModule::ComboAssetsCategory;
|
|
EAssetTypeCategories::Type FComboInputEditorModule::ComboActionGraphCategory;
|
|
|
|
|
|
class FAssetTypeActions_ComboAction : public FAssetTypeActions_DataAsset
|
|
{
|
|
public:
|
|
virtual FText GetName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_ComboAction", "Combo Action"); }
|
|
virtual uint32 GetCategories() override { return FComboInputEditorModule::GetInputAssetsCategory(); }
|
|
virtual FColor GetTypeColor() const override { return FColor(255, 127, 255); }
|
|
virtual FText GetAssetDescription(const FAssetData &AssetData) const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_ComboActionDesc", "An action that can be executed as part of a combo sequence. This is essentially a representation of an attack, and can be sent to the Animation Graph to play an attack animation and the like."); }
|
|
virtual UClass *GetSupportedClass() const override { return UComboAction::StaticClass(); }
|
|
};
|
|
|
|
class FAssetTypeActions_ComboInputAsset : public FAssetTypeActions_DataAsset
|
|
{
|
|
public:
|
|
virtual FText GetName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_ComboInputAsset", "Combo Input Asset"); }
|
|
virtual uint32 GetCategories() override { return FComboInputEditorModule::GetInputAssetsCategory(); }
|
|
virtual FColor GetTypeColor() const override { return FColor(255, 127, 255); }
|
|
virtual FText GetAssetDescription(const FAssetData &AssetData) const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_ComboInputAssetDesc", "This maps a sequence of button inputs from EnhancedInput to a combo action that can be used to execute a sequence of moves. This gets sent from the input buffer subsystem to the player controller's ComboManagerComponent, which executes the associated action in the current ComboActionGraph."); }
|
|
virtual UClass *GetSupportedClass() const override { return UComboInputAsset::StaticClass(); }
|
|
};
|
|
|
|
class FAssetTypeActions_ComboActionGraph : public FAssetTypeActions_Base
|
|
{
|
|
public:
|
|
virtual FText GetName() const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_ComboActionGraph", "Combo Action Graph"); }
|
|
virtual uint32 GetCategories() override { return FComboInputEditorModule::GetInputAssetsCategory(); }
|
|
virtual FColor GetTypeColor() const override { return FColor(255, 127, 255); }
|
|
virtual FText GetAssetDescription(const FAssetData &AssetData) const override { return NSLOCTEXT("AssetTypeActions", "AssetTypeActions_ComboActionGraphDesc", "A node graph containing a sequence of combo actions. Each node can respond to any number of combo inputs, and when activated will execute the associated event."); }
|
|
virtual UClass *GetSupportedClass() const override { return UComboActionGraph::StaticClass(); }
|
|
|
|
virtual void OpenAssetEditor(const TArray<UObject*> &InObjects, TSharedPtr<class IToolkitHost> EditWithinLevelEditor = TSharedPtr<IToolkitHost>()) override
|
|
{
|
|
const EToolkitMode::Type Mode = EditWithinLevelEditor.IsValid() ? EToolkitMode::WorldCentric : EToolkitMode::Standalone;
|
|
for (auto ObjIt = InObjects.CreateConstIterator(); ObjIt; ObjIt++)
|
|
{
|
|
if (UComboActionGraph *Graph = Cast<UComboActionGraph>(*ObjIt))
|
|
{
|
|
TSharedRef<FAssetEditor_ComboActionGraph> NewGraphEditor(new FAssetEditor_ComboActionGraph());
|
|
NewGraphEditor->InitComboActionGraphAssetEditor(Mode, EditWithinLevelEditor, Graph);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
class FComboActionGraphPanelNodeFactory : public FGraphPanelNodeFactory
|
|
{
|
|
public:
|
|
virtual TSharedPtr<class SGraphNode> CreateNode(UEdGraphNode *Node) const override
|
|
{
|
|
|
|
if (UEdComboActionGraphNode *EdGraphNode = Cast<UEdComboActionGraphNode>(Node))
|
|
{
|
|
return SNew(SEdComboActionGraphNode, EdGraphNode);
|
|
}
|
|
else if (UEdComboActionGraphEdge *EdGraphEdge = Cast<UEdComboActionGraphEdge>(Node))
|
|
{
|
|
return SNew(SEdComboActionGraphEdge, EdGraphEdge);
|
|
}
|
|
return nullptr;
|
|
}
|
|
};
|
|
|
|
|
|
UComboAction_Factory::UComboAction_Factory(const FObjectInitializer &ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
this->SupportedClass = UComboAction::StaticClass();
|
|
this->bEditAfterNew = true;
|
|
this->bCreateNew = true;
|
|
}
|
|
|
|
UObject *UComboAction_Factory::FactoryCreateNew(UClass *Class, UObject *InParent, FName Name, EObjectFlags Flags, UObject *Context, FFeedbackContext *Warn)
|
|
{
|
|
if (this->ComboActionClass != nullptr)
|
|
{
|
|
return NewObject<UComboAction>(InParent, this->ComboActionClass, Name, Flags | EObjectFlags::RF_Transactional, Context);
|
|
}
|
|
else
|
|
{
|
|
check(Class->IsChildOf(UComboAction::StaticClass()));
|
|
return NewObject<UComboAction>(InParent, Class, Name, Flags | EObjectFlags::RF_Transactional, Context);
|
|
}
|
|
}
|
|
|
|
|
|
UComboInputAsset_Factory::UComboInputAsset_Factory(const FObjectInitializer &ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
this->SupportedClass = UComboInputAsset::StaticClass();
|
|
this->bEditAfterNew = true;
|
|
this->bCreateNew = true;
|
|
}
|
|
|
|
UObject *UComboInputAsset_Factory::FactoryCreateNew(UClass *Class, UObject *InParent, FName Name, EObjectFlags Flags, UObject *Context, FFeedbackContext *Warn)
|
|
{
|
|
if (this->ComboInputAssetClass != nullptr)
|
|
{
|
|
return NewObject<UComboInputAsset>(InParent, this->ComboInputAssetClass, Name, Flags | EObjectFlags::RF_Transactional, Context);
|
|
}
|
|
else
|
|
{
|
|
check(Class->IsChildOf(UComboInputAsset::StaticClass()));
|
|
return NewObject<UComboInputAsset>(InParent, Class, Name, Flags | EObjectFlags::RF_Transactional, Context);
|
|
}
|
|
}
|
|
|
|
|
|
UComboActionGraph_Factory::UComboActionGraph_Factory(const FObjectInitializer &ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
this->SupportedClass = UComboActionGraph::StaticClass();
|
|
this->bEditAfterNew = true;
|
|
this->bCreateNew = true;
|
|
}
|
|
|
|
UObject *UComboActionGraph_Factory::FactoryCreateNew(UClass *Class, UObject *InParent, FName Name, EObjectFlags Flags, UObject *Context, FFeedbackContext *Warn)
|
|
{
|
|
if (this->ComboActionGraphClass != nullptr)
|
|
{
|
|
return NewObject<UComboActionGraph>(InParent, this->ComboActionGraphClass, Name, Flags | EObjectFlags::RF_Transactional, Context);
|
|
}
|
|
else
|
|
{
|
|
check(Class->IsChildOf(UComboActionGraph::StaticClass()));
|
|
return NewObject<UComboActionGraph>(InParent, Class, Name, Flags | EObjectFlags::RF_Transactional, Context);
|
|
}
|
|
}
|
|
|
|
|
|
FComboInputSlateStyle::FComboInputSlateStyle() : FSlateStyleSet("ComboInputEditor")
|
|
{
|
|
this->SetParentStyleName(FAppStyle::GetAppStyleSetName());
|
|
|
|
const FString &PluginSlateDir = IPluginManager::Get().FindPlugin("ComboInput")->GetBaseDir();
|
|
|
|
this->SetContentRoot(PluginSlateDir / TEXT("Resources/Slate"));
|
|
this->SetCoreContentRoot(FPaths::EngineContentDir() / TEXT("Slate"));
|
|
|
|
// Combo Input Editor icons
|
|
static const FVector2D Icon12(12.0f, 12.0f);
|
|
static const FVector2D Icon16(16.0f, 16.0f);
|
|
static const FVector2D Icon40(40.0f, 40.0f);
|
|
static const FVector2D Icon64(64.0f, 64.0f);
|
|
|
|
this->Set("ComboInputIcon_Small", new IMAGE_BRUSH_SVG("Icons/ComboInput_16", Icon16));
|
|
this->Set("ComboInputIcon_Large", new IMAGE_BRUSH_SVG("Icons/ComboInput_64", Icon64));
|
|
|
|
this->Set("ClassIcon.ComboAction", new IMAGE_BRUSH_SVG("Icons/ComboAction_16", Icon16));
|
|
this->Set("ClassThumbnail.ComboAction", new IMAGE_BRUSH_SVG("Icons/ComboAction_64", Icon64));
|
|
|
|
this->Set("ClassIcon.ComboSequenceNode", new IMAGE_BRUSH_SVG("Icons/ComboSequenceNode_16", Icon16));
|
|
this->Set("ClassThumbnail.ComboSequenceNode", new IMAGE_BRUSH_SVG("Icons/ComboSequenceNode_64", Icon64));
|
|
|
|
this->Set("ClassIcon.ComboInputAsset", new IMAGE_BRUSH_SVG("Icons/ComboInputAsset_16", Icon16));
|
|
this->Set("ClassThumbnail.ComboInputAsset", new IMAGE_BRUSH_SVG("Icons/ComboInputAsset_64", Icon64));
|
|
|
|
this->Set("ClassIcon.ComboActionGraph", new IMAGE_BRUSH_SVG("Icons/ComboSequenceNode_16", Icon16));
|
|
this->Set("ClassThumbnail.ComboActionGraph", new IMAGE_BRUSH_SVG("Icons/ComboSequenceNode_64", Icon64));
|
|
|
|
// Combo Action Graph editor brushes
|
|
{
|
|
this->SetContentRoot(PluginSlateDir / TEXT("Resources/Slate/Editor"));
|
|
this->SetCoreContentRoot(FPaths::EngineContentDir() / TEXT("Slate/Editor"));
|
|
|
|
this->Set("MDSStyleSet.AutoArrange.small", new IMAGE_BRUSH(TEXT("AutoArrangeIcon"), Icon16));
|
|
this->Set("MDSStyleSet.AutoArrange", new IMAGE_BRUSH(TEXT("AutoArrangeIcon"), Icon40));
|
|
this->Set("MDSStyleSet.AutoArrange.large", new IMAGE_BRUSH(TEXT("AutoArrangeIcon"), Icon64));
|
|
|
|
this->Set("MDSStyleSet.GraphSettings.small", new IMAGE_BRUSH(TEXT("GraphSettings"), Icon16));
|
|
this->Set("MDSStyleSet.GraphSettings", new IMAGE_BRUSH(TEXT("GraphSettings"), Icon40));
|
|
this->Set("MDSStyleSet.GraphSettings.large", new IMAGE_BRUSH(TEXT("GraphSettings"), Icon64));
|
|
|
|
this->Set("MDSStyleSet.ValidateGraph.small", new IMAGE_BRUSH(TEXT("ValidateGraph"), Icon16));
|
|
this->Set("MDSStyleSet.ValidateGraph", new IMAGE_BRUSH(TEXT("ValidateGraph"), Icon40));
|
|
this->Set("MDSStyleSet.ValidateGraph.large", new IMAGE_BRUSH(TEXT("ValidateGraph"), Icon64));
|
|
|
|
this->Set("MDSStyleSet.Graph.NodeOverlay", new BOX_BRUSH(TEXT("NodeOverlay"), FMargin(8.0f / 64.0f, 3.0f / 32.0f, 0, 0)));
|
|
this->Set("MDSStyleSet.Graph.PinDocksOverlay", new BOX_BRUSH(TEXT("PinDocksOverlay"), FMargin(8.0f / 64.0f, 3.0f / 32.0f, 0, 0)));
|
|
|
|
this->Set("MDSStyleSet.Graph.SimpleArrow", new IMAGE_BRUSH(TEXT("SimpleArrow"), Icon16));
|
|
this->Set("MDSStyleSet.Graph.HollowArrow", new IMAGE_BRUSH(TEXT("HollowArrow"), Icon16));
|
|
this->Set("MDSStyleSet.Graph.FancyArrow", new IMAGE_BRUSH(TEXT("FancyArrow"), Icon16));
|
|
this->Set("MDSStyleSet.Graph.Bubble", new IMAGE_BRUSH(TEXT("Bubble"), Icon16));
|
|
|
|
this->Set("MDSStyleSet.Node.SoftEdges", new BOX_BRUSH(TEXT("NodeSoftCorners"), FMargin(16.f / 64.f, 25.f / 64.f, 16.f / 64.f, 16.f / 64.f)));
|
|
this->Set("MDSStyleSet.Node.HardEdges", new BOX_BRUSH(TEXT("NodeHardCorners"), FMargin(16.f / 64.f, 25.f / 64.f, 16.f / 64.f, 16.f / 64.f)));
|
|
|
|
this->Set("MDSStyleSet.Node.TextSoftEdges", new BOX_BRUSH(TEXT("TextSoftCorners"), FMargin(16.f / 64.f, 25.f / 64.f, 16.f / 64.f, 16.f / 64.f)));
|
|
this->Set("MDSStyleSet.Node.TextHardEdges", new BOX_BRUSH(TEXT("TextHardCorners"), FMargin(16.f / 64.f, 25.f / 64.f, 16.f / 64.f, 16.f / 64.f)));
|
|
|
|
this->Set("MDSStyleSet.Node.IndexCircle", new IMAGE_BRUSH(TEXT("IndexIcon"), Icon16));
|
|
|
|
this->Set("MDSStyleSet.Icon.OK", new IMAGE_BRUSH(TEXT("OKIcon"), Icon16));
|
|
this->Set("MDSStyleSet.Icon.Error", new IMAGE_BRUSH(TEXT("ErroIcon"), Icon16));
|
|
this->Set("MDSStyleSet.Icon.BulletPoint", new IMAGE_BRUSH(TEXT("CircleBox"), Icon16));
|
|
|
|
this->Set("MDSStyleSet.Graph.CornerImage", new IMAGE_BRUSH(TEXT("Icon128"), FVector2D(128.0f, 128.0f)));
|
|
|
|
this->Set("MDSStyleSet.Icon.Browse", new IMAGE_BRUSH(TEXT("BrowseIcon"), Icon12));
|
|
this->Set("MDSStyleSet.Icon.Edit", new IMAGE_BRUSH(TEXT("EditIcon"), Icon12));
|
|
|
|
this->Set("MDSStyleSet.Buttons.Documentation", new IMAGE_BRUSH(TEXT("Documentation"), FVector2D(200.0f, 70.0f)));
|
|
this->Set("MDSStyleSet.Buttons.Documentation.small", new IMAGE_BRUSH(TEXT("DocumentationIcon"), Icon12));
|
|
|
|
this->Set("MDSStyleSet.Node.Icon.large", new IMAGE_BRUSH(TEXT("DialogueNodeIcon"), Icon64));
|
|
this->Set("MDSStyleSet.Node.Icon", new IMAGE_BRUSH(TEXT("DialogueNodeIcon"), Icon16));
|
|
this->Set("MDSStyleSet.Node.Icon.small", new IMAGE_BRUSH(TEXT("DialogueNodeIcon"), Icon12));
|
|
|
|
this->Set("MDSStyleSet.Icon.Close", new IMAGE_BRUSH(TEXT("CloseIcon"), Icon12));
|
|
this->Set("MDSStyleSet.Icon.SupportDiscord", new IMAGE_BRUSH(TEXT("DiscordIcon"), Icon12));
|
|
this->Set("MDSStyleSet.Icon.HeartIcon", new IMAGE_BRUSH(TEXT("HeartIcon"), Icon12));
|
|
this->Set("MDSStyleSet.Icon.UBIcon", new IMAGE_BRUSH(TEXT("UnrealBucketIcon"), Icon12));
|
|
this->Set("MDSStyleSet.Icon.MoneyIcon", new IMAGE_BRUSH(TEXT("MoneyIcon"), Icon12));
|
|
|
|
this->Set("MDSStyleSet.Buttons.Style", FButtonStyle()
|
|
.SetNormal(BOX_BRUSH("RoundedSelection_16x", 4.0f / 16.0f, FLinearColor(1, 1, 1, 0.1f)))
|
|
.SetHovered(BOX_BRUSH("RoundedSelection_16x", 4.0f / 16.0f, FLinearColor(1, .55f, 0, 0.2f)))
|
|
.SetPressed(BOX_BRUSH("RoundedSelection_16x", 4.0f / 16.0f, FLinearColor(1, .55f, 0, 0.4f))));
|
|
const FScrollBarStyle ScrollBar = GetWidgetStyle<FScrollBarStyle>("ScrollBar");
|
|
|
|
FTextBlockStyle NormalText = FTextBlockStyle()
|
|
.SetFont(DEFAULT_FONT("Regular", FCoreStyle::RegularTextSize))
|
|
.SetColorAndOpacity(FSlateColor::UseForeground())
|
|
.SetShadowOffset(FVector2D::ZeroVector)
|
|
.SetShadowColorAndOpacity(FLinearColor::Black)
|
|
.SetHighlightColor(FLinearColor(0.02f, 0.3f, 0.0f))
|
|
.SetHighlightShape(BOX_BRUSH("TextBlockHighlightShape", FMargin(3.f / 8.f)));
|
|
|
|
FTextBlockStyle NodeTitle = FTextBlockStyle(NormalText)
|
|
.SetFont(DEFAULT_FONT("Bold", 14))
|
|
.SetColorAndOpacity(FLinearColor(230.0f / 255.0f, 230.0f / 255.0f, 230.0f / 255.0f))
|
|
.SetShadowOffset(FVector2D(2, 2))
|
|
.SetShadowColorAndOpacity(FLinearColor(0.f, 0.f, 0.f, 0.7f));
|
|
this->Set("MDSStyleSet.NodeTitle", NodeTitle);
|
|
|
|
FEditableTextBoxStyle NodeTitleEditableText = FEditableTextBoxStyle()
|
|
.SetFont(NormalText.Font)
|
|
.SetBackgroundImageNormal(BOX_BRUSH("TextBox", FMargin(4.0f / 16.0f)))
|
|
.SetBackgroundImageHovered(BOX_BRUSH("TextBox_Hovered", FMargin(4.0f / 16.0f)))
|
|
.SetBackgroundImageFocused(BOX_BRUSH("TextBox_Hovered", FMargin(4.0f / 16.0f)))
|
|
.SetBackgroundImageReadOnly(BOX_BRUSH("TextBox_ReadOnly", FMargin(4.0f / 16.0f)))
|
|
.SetScrollBarStyle(ScrollBar);
|
|
this->Set("MDSStyleSet.NodeTitleEditableText", NodeTitleEditableText);
|
|
|
|
this->Set("MDSStyleSet.NodeTitleInlineEditableText", FInlineEditableTextBlockStyle()
|
|
.SetTextStyle(NodeTitle)
|
|
.SetEditableTextBoxStyle(NodeTitleEditableText)
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
void FComboInputEditorModule::StartupModule()
|
|
{
|
|
// Register combo action asset
|
|
IAssetTools &AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get();
|
|
FComboInputEditorModule::ComboAssetsCategory = AssetTools.RegisterAdvancedAssetCategory(FName(TEXT("Combo Input")), LOCTEXT("ComboInputAssetsCategory", "Combo Input"));
|
|
this->RegisterAssetTypeActions(AssetTools, MakeShareable(new FAssetTypeActions_ComboAction));
|
|
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
|
|
this->ComboInputEditorStyleSet = MakeShared<FComboInputSlateStyle>();
|
|
FSlateStyleRegistry::RegisterSlateStyle(*this->ComboInputEditorStyleSet.Get());
|
|
|
|
// Combo Action Graph
|
|
{
|
|
this->ComboActionGraphPanelNodeFactory = MakeShareable(new FComboActionGraphPanelNodeFactory());
|
|
FEdGraphUtilities::RegisterVisualNodeFactory(this->ComboActionGraphPanelNodeFactory);
|
|
|
|
// Register asset actions
|
|
this->ComboActionGraphAssetActions = MakeShared<FAssetTypeActions_ComboActionGraph>();
|
|
this->RegisterAssetTypeActions(AssetTools, this->ComboActionGraphAssetActions.ToSharedRef());
|
|
}
|
|
|
|
FComboActionGraphEditorCommands::Register();
|
|
}
|
|
|
|
void FComboInputEditorModule::ShutdownModule()
|
|
{
|
|
FComboActionGraphEditorCommands::Unregister();
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|
|
|
|
IMPLEMENT_MODULE(FComboInputEditorModule, ComboInputEditorModule)
|