├── .gitignore ├── AssetTutorialPlugin.uplugin ├── LICENSE ├── README.md ├── Resources └── Icon128.png └── Source ├── AssetTutorialPlugin ├── AssetTutorialPlugin.Build.cs ├── Private │ ├── AssetTutorialPlugin.cpp │ └── NormalDistribution.cpp └── Public │ ├── AssetTutorialPlugin.h │ └── NormalDistribution.h └── AssetTutorialPluginEditor ├── AssetTutorialPluginEditor.Build.cs ├── Private ├── AssetTutorialPluginEditor.cpp ├── NormalDistributionActions.cpp ├── NormalDistributionEditorToolkit.cpp ├── NormalDistributionFactory.cpp └── SNormalDistributionWidget.cpp └── Public ├── AssetTutorialPluginEditor.h ├── NormalDistributionActions.h ├── NormalDistributionEditorToolkit.h ├── NormalDistributionFactory.h └── SNormalDistributionWidget.h /.gitignore: -------------------------------------------------------------------------------- 1 | Binaries 2 | Intermediate 3 | -------------------------------------------------------------------------------- /AssetTutorialPlugin.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "AssetTutorialPlugin", 6 | "Description": "", 7 | "Category": "Other", 8 | "CreatedBy": "", 9 | "CreatedByURL": "", 10 | "DocsURL": "", 11 | "MarketplaceURL": "", 12 | "SupportURL": "", 13 | "CanContainContent": true, 14 | "IsBetaVersion": false, 15 | "IsExperimentalVersion": false, 16 | "Installed": false, 17 | "Modules": [ 18 | { 19 | "Name": "AssetTutorialPlugin", 20 | "Type": "Runtime", 21 | "LoadingPhase": "Default" 22 | }, 23 | { 24 | "Name": "AssetTutorialPluginEditor", 25 | "Type": "Editor", 26 | "LoadingPhase": "Default" 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 JanKXSKI 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is the source code for the "Creating A Custom Asset Type With Its Own Editor In C++" tutorial over at https://dev.epicgames.com/community/learning/tutorials/vyKB/unreal-engine-creating-a-custom-asset-type-with-its-own-editor-in-c. -------------------------------------------------------------------------------- /Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JanKXSKI/AssetTutorialPlugin/8c6f3fc4fe23c6d1f103f49883ccaf6681302206/Resources/Icon128.png -------------------------------------------------------------------------------- /Source/AssetTutorialPlugin/AssetTutorialPlugin.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class AssetTutorialPlugin : ModuleRules 6 | { 7 | public AssetTutorialPlugin(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | // ... add public include paths required here ... 14 | } 15 | ); 16 | 17 | 18 | PrivateIncludePaths.AddRange( 19 | new string[] { 20 | // ... add other private include paths required here ... 21 | } 22 | ); 23 | 24 | 25 | PublicDependencyModuleNames.AddRange( 26 | new string[] 27 | { 28 | "Core", 29 | // ... add other public dependencies that you statically link with here ... 30 | } 31 | ); 32 | 33 | 34 | PrivateDependencyModuleNames.AddRange( 35 | new string[] 36 | { 37 | "CoreUObject", 38 | "Engine", 39 | "Slate", 40 | "SlateCore", 41 | // ... add private dependencies that you statically link with here ... 42 | } 43 | ); 44 | 45 | 46 | DynamicallyLoadedModuleNames.AddRange( 47 | new string[] 48 | { 49 | // ... add any modules that your module loads dynamically here ... 50 | } 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Source/AssetTutorialPlugin/Private/AssetTutorialPlugin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "AssetTutorialPlugin.h" 4 | 5 | #define LOCTEXT_NAMESPACE "FAssetTutorialPluginModule" 6 | 7 | void FAssetTutorialPluginModule::StartupModule() 8 | { 9 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 10 | } 11 | 12 | void FAssetTutorialPluginModule::ShutdownModule() 13 | { 14 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 15 | // we call this function before unloading the module. 16 | } 17 | 18 | #undef LOCTEXT_NAMESPACE 19 | 20 | IMPLEMENT_MODULE(FAssetTutorialPluginModule, AssetTutorialPlugin) -------------------------------------------------------------------------------- /Source/AssetTutorialPlugin/Private/NormalDistribution.cpp: -------------------------------------------------------------------------------- 1 | #include "NormalDistribution.h" 2 | 3 | UNormalDistribution::UNormalDistribution() 4 | : Mean(0.5f) 5 | , StandardDeviation(0.2f) 6 | {} 7 | 8 | float UNormalDistribution::DrawSample() 9 | { 10 | return std::normal_distribution<>(Mean, StandardDeviation)(RandomNumberGenerator); 11 | } 12 | 13 | void UNormalDistribution::LogSample() 14 | { 15 | UE_LOG(LogTemp, Log, TEXT("%f"), DrawSample()) 16 | } 17 | -------------------------------------------------------------------------------- /Source/AssetTutorialPlugin/Public/AssetTutorialPlugin.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Modules/ModuleManager.h" 7 | 8 | class FAssetTutorialPluginModule : public IModuleInterface 9 | { 10 | public: 11 | 12 | /** IModuleInterface implementation */ 13 | virtual void StartupModule() override; 14 | virtual void ShutdownModule() override; 15 | }; 16 | -------------------------------------------------------------------------------- /Source/AssetTutorialPlugin/Public/NormalDistribution.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "UObject/NoExportTypes.h" 5 | #include 6 | #include "NormalDistribution.generated.h" 7 | 8 | UCLASS(BlueprintType) 9 | class ASSETTUTORIALPLUGIN_API UNormalDistribution : public UObject 10 | { 11 | GENERATED_BODY() 12 | public: 13 | UNormalDistribution(); 14 | 15 | UPROPERTY(EditAnywhere) 16 | float Mean; 17 | 18 | UPROPERTY(EditAnywhere) 19 | float StandardDeviation; 20 | 21 | UFUNCTION(BlueprintCallable) 22 | float DrawSample(); 23 | 24 | UFUNCTION(CallInEditor) 25 | void LogSample(); 26 | private: 27 | std::mt19937 RandomNumberGenerator; 28 | }; 29 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/AssetTutorialPluginEditor.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class AssetTutorialPluginEditor : ModuleRules 6 | { 7 | public AssetTutorialPluginEditor(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | // ... add public include paths required here ... 14 | } 15 | ); 16 | 17 | 18 | PrivateIncludePaths.AddRange( 19 | new string[] { 20 | // ... add other private include paths required here ... 21 | } 22 | ); 23 | 24 | 25 | PublicDependencyModuleNames.AddRange( 26 | new string[] 27 | { 28 | "Core", 29 | // ... add other public dependencies that you statically link with here ... 30 | } 31 | ); 32 | 33 | 34 | PrivateDependencyModuleNames.AddRange( 35 | new string[] 36 | { 37 | "CoreUObject", 38 | "Engine", 39 | "Slate", 40 | "SlateCore", 41 | "AssetTutorialPlugin", 42 | "UnrealEd" 43 | // ... add private dependencies that you statically link with here ... 44 | } 45 | ); 46 | 47 | 48 | DynamicallyLoadedModuleNames.AddRange( 49 | new string[] 50 | { 51 | // ... add any modules that your module loads dynamically here ... 52 | } 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/Private/AssetTutorialPluginEditor.cpp: -------------------------------------------------------------------------------- 1 | #include "AssetTutorialPluginEditor.h" 2 | 3 | void FAssetTutorialPluginEditorModule::StartupModule() 4 | { 5 | NormalDistributionAssetTypeActions = MakeShared(); 6 | FAssetToolsModule::GetModule().Get().RegisterAssetTypeActions(NormalDistributionAssetTypeActions.ToSharedRef()); 7 | } 8 | 9 | void FAssetTutorialPluginEditorModule::ShutdownModule() 10 | { 11 | if (!FModuleManager::Get().IsModuleLoaded("AssetTools")) return; 12 | FAssetToolsModule::GetModule().Get().UnregisterAssetTypeActions(NormalDistributionAssetTypeActions.ToSharedRef()); 13 | } 14 | 15 | IMPLEMENT_MODULE(FAssetTutorialPluginEditorModule, AssetTutorialPluginEditor) 16 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/Private/NormalDistributionActions.cpp: -------------------------------------------------------------------------------- 1 | #include "NormalDistributionActions.h" 2 | #include "NormalDistribution.h" 3 | #include "NormalDistributionEditorToolkit.h" 4 | 5 | UClass* FNormalDistributionAssetTypeActions::GetSupportedClass() const 6 | { 7 | return UNormalDistribution::StaticClass(); 8 | } 9 | 10 | FText FNormalDistributionAssetTypeActions::GetName() const 11 | { 12 | return INVTEXT("Normal Distribution"); 13 | } 14 | 15 | FColor FNormalDistributionAssetTypeActions::GetTypeColor() const 16 | { 17 | return FColor::Cyan; 18 | } 19 | 20 | uint32 FNormalDistributionAssetTypeActions::GetCategories() 21 | { 22 | return EAssetTypeCategories::Misc; 23 | } 24 | 25 | void FNormalDistributionAssetTypeActions::OpenAssetEditor(const TArray& InObjects, TSharedPtr EditWithinLevelEditor) 26 | { 27 | MakeShared()->InitEditor(InObjects); 28 | } 29 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/Private/NormalDistributionEditorToolkit.cpp: -------------------------------------------------------------------------------- 1 | #include "NormalDistributionEditorToolkit.h" 2 | #include "Widgets/Docking/SDockTab.h" 3 | #include "SNormalDistributionWidget.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | void FNormalDistributionEditorToolkit::InitEditor(const TArray& InObjects) 7 | { 8 | NormalDistribution = Cast(InObjects[0]); 9 | 10 | const TSharedRef Layout = FTabManager::NewLayout("NormalDistributionEditorLayout") 11 | ->AddArea 12 | ( 13 | FTabManager::NewPrimaryArea()->SetOrientation(Orient_Vertical) 14 | ->Split 15 | ( 16 | FTabManager::NewSplitter() 17 | ->SetSizeCoefficient(0.6f) 18 | ->SetOrientation(Orient_Horizontal) 19 | ->Split 20 | ( 21 | FTabManager::NewStack() 22 | ->SetSizeCoefficient(0.8f) 23 | ->AddTab("NormalDistributionPDFTab", ETabState::OpenedTab) 24 | ) 25 | ->Split 26 | ( 27 | FTabManager::NewStack() 28 | ->SetSizeCoefficient(0.2f) 29 | ->AddTab("NormalDistributionDetailsTab", ETabState::OpenedTab) 30 | ) 31 | ) 32 | ->Split 33 | ( 34 | FTabManager::NewStack() 35 | ->SetSizeCoefficient(0.4f) 36 | ->AddTab("OutputLog", ETabState::OpenedTab) 37 | ) 38 | ); 39 | FAssetEditorToolkit::InitAssetEditor(EToolkitMode::Standalone, {}, "NormalDistributionEditor", Layout, true, true, InObjects); 40 | } 41 | 42 | void FNormalDistributionEditorToolkit::RegisterTabSpawners(const TSharedRef& InTabManager) 43 | { 44 | FAssetEditorToolkit::RegisterTabSpawners(InTabManager); 45 | 46 | WorkspaceMenuCategory = InTabManager->AddLocalWorkspaceMenuCategory(INVTEXT("Normal Distribution Editor")); 47 | 48 | InTabManager->RegisterTabSpawner("NormalDistributionPDFTab", FOnSpawnTab::CreateLambda([=](const FSpawnTabArgs&) 49 | { 50 | return SNew(SDockTab) 51 | [ 52 | SNew(SNormalDistributionWidget) 53 | .Mean(this, &FNormalDistributionEditorToolkit::GetMean) 54 | .StandardDeviation(this, &FNormalDistributionEditorToolkit::GetStandardDeviation) 55 | .OnMeanChanged(this, &FNormalDistributionEditorToolkit::SetMean) 56 | .OnStandardDeviationChanged(this, &FNormalDistributionEditorToolkit::SetStandardDeviation) 57 | ]; 58 | })) 59 | .SetDisplayName(INVTEXT("PDF")) 60 | .SetGroup(WorkspaceMenuCategory.ToSharedRef()); 61 | 62 | FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked("PropertyEditor"); 63 | FDetailsViewArgs DetailsViewArgs; 64 | DetailsViewArgs.NameAreaSettings = FDetailsViewArgs::HideNameArea; 65 | TSharedRef DetailsView = PropertyEditorModule.CreateDetailView(DetailsViewArgs); 66 | DetailsView->SetObjects(TArray{ NormalDistribution }); 67 | InTabManager->RegisterTabSpawner("NormalDistributionDetailsTab", FOnSpawnTab::CreateLambda([=](const FSpawnTabArgs&) 68 | { 69 | return SNew(SDockTab) 70 | [ 71 | DetailsView 72 | ]; 73 | })) 74 | .SetDisplayName(INVTEXT("Details")) 75 | .SetGroup(WorkspaceMenuCategory.ToSharedRef()); 76 | } 77 | 78 | void FNormalDistributionEditorToolkit::UnregisterTabSpawners(const TSharedRef& InTabManager) 79 | { 80 | FAssetEditorToolkit::UnregisterTabSpawners(InTabManager); 81 | InTabManager->UnregisterTabSpawner("NormalDistributionPDFTab"); 82 | InTabManager->UnregisterTabSpawner("NormalDistributionDetailsTab"); 83 | } 84 | 85 | float FNormalDistributionEditorToolkit::GetMean() const 86 | { 87 | return NormalDistribution->Mean; 88 | } 89 | 90 | float FNormalDistributionEditorToolkit::GetStandardDeviation() const 91 | { 92 | return NormalDistribution->StandardDeviation; 93 | } 94 | 95 | void FNormalDistributionEditorToolkit::SetMean(float Mean) 96 | { 97 | NormalDistribution->Modify(); 98 | NormalDistribution->Mean = Mean; 99 | } 100 | 101 | void FNormalDistributionEditorToolkit::SetStandardDeviation(float StandardDeviation) 102 | { 103 | NormalDistribution->Modify(); 104 | NormalDistribution->StandardDeviation = StandardDeviation; 105 | } 106 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/Private/NormalDistributionFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "NormalDistributionFactory.h" 2 | #include "NormalDistribution.h" 3 | 4 | UNormalDistributionFactory::UNormalDistributionFactory() 5 | { 6 | SupportedClass = UNormalDistribution::StaticClass(); 7 | bCreateNew = true; 8 | } 9 | 10 | UObject* UNormalDistributionFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) 11 | { 12 | return NewObject(InParent, Class, Name, Flags, Context); 13 | } 14 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/Private/SNormalDistributionWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "SNormalDistributionWidget.h" 2 | #include "Editor.h" 3 | 4 | void SNormalDistributionWidget::Construct(const FArguments& InArgs) 5 | { 6 | Mean = InArgs._Mean; 7 | StandardDeviation = InArgs._StandardDeviation; 8 | OnMeanChanged = InArgs._OnMeanChanged; 9 | OnStandardDeviationChanged = InArgs._OnStandardDeviationChanged; 10 | } 11 | 12 | int32 SNormalDistributionWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const 13 | { 14 | const int32 NumPoints = 512; 15 | TArray Points; 16 | Points.Reserve(NumPoints); 17 | const FTransform2D PointsTransform = GetPointsTransform(AllottedGeometry); 18 | for (int32 PointIndex = 0; PointIndex < NumPoints; ++PointIndex) 19 | { 20 | const float X = PointIndex / (NumPoints - 1.0); 21 | const float D = (X - Mean.Get()) / StandardDeviation.Get(); 22 | const float Y = FMath::Exp(-0.5f * D * D); 23 | Points.Add(PointsTransform.TransformPoint(FVector2D(X, Y))); 24 | } 25 | FSlateDrawElement::MakeLines(OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), Points); 26 | return LayerId; 27 | } 28 | 29 | FVector2D SNormalDistributionWidget::ComputeDesiredSize(float) const 30 | { 31 | return FVector2D(200.0, 200.0); 32 | } 33 | 34 | FReply SNormalDistributionWidget::OnMouseButtonDown(const FGeometry& AllottedGeometry, const FPointerEvent& MouseEvent) 35 | { 36 | if (GEditor && GEditor->CanTransact() && ensure(!GIsTransacting)) 37 | GEditor->BeginTransaction(TEXT(""), INVTEXT("Edit Normal Distribution"), nullptr); 38 | return FReply::Handled().CaptureMouse(SharedThis(this)); 39 | } 40 | 41 | FReply SNormalDistributionWidget::OnMouseButtonUp(const FGeometry& AllottedGeometry, const FPointerEvent& MouseEvent) 42 | { 43 | if (GEditor) GEditor->EndTransaction(); 44 | return FReply::Handled().ReleaseMouseCapture(); 45 | } 46 | 47 | FReply SNormalDistributionWidget::OnMouseMove(const FGeometry& AllottedGeometry, const FPointerEvent& MouseEvent) 48 | { 49 | if (!HasMouseCapture()) return FReply::Unhandled(); 50 | const FTransform2D PointsTransform = GetPointsTransform(AllottedGeometry); 51 | const FVector2D LocalPosition = AllottedGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()); 52 | const FVector2D NormalizedPosition = PointsTransform.Inverse().TransformPoint(LocalPosition); 53 | if (OnMeanChanged.IsBound()) 54 | OnMeanChanged.Execute(NormalizedPosition.X); 55 | if (OnStandardDeviationChanged.IsBound()) 56 | OnStandardDeviationChanged.Execute(FMath::Max(0.025f, FMath::Lerp(0.025f, 0.25f, NormalizedPosition.Y))); 57 | return FReply::Handled(); 58 | } 59 | 60 | FTransform2D SNormalDistributionWidget::GetPointsTransform(const FGeometry& AllottedGeometry) const 61 | { 62 | const double Margin = 0.05 * AllottedGeometry.GetLocalSize().GetMin(); 63 | const FScale2D Scale((AllottedGeometry.GetLocalSize() - 2.0 * Margin) * FVector2D(1.0, -1.0)); 64 | const FVector2D Translation(Margin, AllottedGeometry.GetLocalSize().Y - Margin); 65 | return FTransform2D(Scale, Translation); 66 | } 67 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/Public/AssetTutorialPluginEditor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Modules/ModuleManager.h" 5 | #include "NormalDistributionActions.h" 6 | 7 | class FAssetTutorialPluginEditorModule : public IModuleInterface 8 | { 9 | public: 10 | void StartupModule() override; 11 | void ShutdownModule() override; 12 | private: 13 | TSharedPtr NormalDistributionAssetTypeActions; 14 | }; 15 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/Public/NormalDistributionActions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "AssetTypeActions_Base.h" 5 | 6 | class FNormalDistributionAssetTypeActions : public FAssetTypeActions_Base 7 | { 8 | public: 9 | UClass* GetSupportedClass() const override; 10 | FText GetName() const override; 11 | FColor GetTypeColor() const override; 12 | uint32 GetCategories() override; 13 | void OpenAssetEditor(const TArray& InObjects, TSharedPtr EditWithinLevelEditor) override; 14 | }; 15 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/Public/NormalDistributionEditorToolkit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "NormalDistribution.h" 5 | #include "Toolkits/AssetEditorToolkit.h" 6 | 7 | class FNormalDistributionEditorToolkit : public FAssetEditorToolkit 8 | { 9 | public: 10 | void InitEditor(const TArray& InObjects); 11 | 12 | void RegisterTabSpawners(const TSharedRef& TabManager) override; 13 | void UnregisterTabSpawners(const TSharedRef& TabManager) override; 14 | 15 | FName GetToolkitFName() const override { return "NormalDistributionEditor"; } 16 | FText GetBaseToolkitName() const override { return INVTEXT("Normal Distribution Editor"); } 17 | FString GetWorldCentricTabPrefix() const override { return "Normal Distribution "; } 18 | FLinearColor GetWorldCentricTabColorScale() const override { return {}; } 19 | 20 | float GetMean() const; 21 | float GetStandardDeviation() const; 22 | void SetMean(float Mean); 23 | void SetStandardDeviation(float StandardDeviation); 24 | private: 25 | UNormalDistribution* NormalDistribution; 26 | }; 27 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/Public/NormalDistributionFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Factories/Factory.h" 5 | #include "NormalDistributionFactory.generated.h" 6 | 7 | UCLASS() 8 | class UNormalDistributionFactory : public UFactory 9 | { 10 | GENERATED_BODY() 11 | public: 12 | UNormalDistributionFactory(); 13 | UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn); 14 | }; 15 | -------------------------------------------------------------------------------- /Source/AssetTutorialPluginEditor/Public/SNormalDistributionWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Widgets/SLeafWidget.h" 5 | 6 | DECLARE_DELEGATE_OneParam(FOnMeanChanged, float /*NewMean*/) 7 | DECLARE_DELEGATE_OneParam(FOnStandardDeviationChanged, float /*NewStandardDeviation*/) 8 | 9 | class SNormalDistributionWidget : public SLeafWidget 10 | { 11 | public: 12 | SLATE_BEGIN_ARGS(SNormalDistributionWidget) 13 | : _Mean(0.5f) 14 | , _StandardDeviation(0.2f) 15 | {} 16 | SLATE_ATTRIBUTE(float, Mean) 17 | SLATE_ATTRIBUTE(float, StandardDeviation) 18 | SLATE_EVENT(FOnMeanChanged, OnMeanChanged) 19 | SLATE_EVENT(FOnStandardDeviationChanged, OnStandardDeviationChanged) 20 | SLATE_END_ARGS() 21 | 22 | void Construct(const FArguments& InArgs); 23 | 24 | int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override; 25 | FVector2D ComputeDesiredSize(float) const override; 26 | 27 | FReply OnMouseButtonDown(const FGeometry& AllottedGeometry, const FPointerEvent& MouseEvent) override; 28 | FReply OnMouseButtonUp(const FGeometry& AllottedGeometry, const FPointerEvent& MouseEvent) override; 29 | FReply OnMouseMove(const FGeometry& AllottedGeometry, const FPointerEvent& MouseEvent) override; 30 | private: 31 | TAttribute Mean; 32 | TAttribute StandardDeviation; 33 | 34 | FOnMeanChanged OnMeanChanged; 35 | FOnStandardDeviationChanged OnStandardDeviationChanged; 36 | 37 | FTransform2D GetPointsTransform(const FGeometry& AllottedGeometry) const; 38 | }; 39 | --------------------------------------------------------------------------------