diff --git a/ProjectFish/Content/Characters/BP_PawnEntity.uasset b/ProjectFish/Content/Characters/BP_PawnEntity.uasset index 2b5c7fa..95b3f3f 100644 Binary files a/ProjectFish/Content/Characters/BP_PawnEntity.uasset and b/ProjectFish/Content/Characters/BP_PawnEntity.uasset differ diff --git a/ProjectFish/Content/Gameplay/BP_Dabaza_GameMode.uasset b/ProjectFish/Content/Gameplay/BP_Dabaza_GameMode.uasset index a47af8d..c715d86 100644 Binary files a/ProjectFish/Content/Gameplay/BP_Dabaza_GameMode.uasset and b/ProjectFish/Content/Gameplay/BP_Dabaza_GameMode.uasset differ diff --git a/ProjectFish/Content/__ExternalActors__/Maps/Dabaza/8/VO/DV1AKH9EUYVRMVYP3DYZVH.uasset b/ProjectFish/Content/__ExternalActors__/Maps/Dabaza/8/VO/DV1AKH9EUYVRMVYP3DYZVH.uasset index 62b9e1c..9d5cfa3 100644 Binary files a/ProjectFish/Content/__ExternalActors__/Maps/Dabaza/8/VO/DV1AKH9EUYVRMVYP3DYZVH.uasset and b/ProjectFish/Content/__ExternalActors__/Maps/Dabaza/8/VO/DV1AKH9EUYVRMVYP3DYZVH.uasset differ diff --git a/ProjectFish/Content/__ExternalActors__/Maps/Dabaza/9/GX/KCVNFI6L6PBCQ844W3A926.uasset b/ProjectFish/Content/__ExternalActors__/Maps/Dabaza/9/GX/KCVNFI6L6PBCQ844W3A926.uasset index 651eddb..a879706 100644 Binary files a/ProjectFish/Content/__ExternalActors__/Maps/Dabaza/9/GX/KCVNFI6L6PBCQ844W3A926.uasset and b/ProjectFish/Content/__ExternalActors__/Maps/Dabaza/9/GX/KCVNFI6L6PBCQ844W3A926.uasset differ diff --git a/ProjectFish/ProjectFish.uproject b/ProjectFish/ProjectFish.uproject index 984b23e..cf96cc2 100644 --- a/ProjectFish/ProjectFish.uproject +++ b/ProjectFish/ProjectFish.uproject @@ -8,6 +8,11 @@ "Name": "ProjectFish", "Type": "Runtime", "LoadingPhase": "Default" + }, + { + "Name": "ProjectFishEditor", + "Type": "Editor", + "LoadingPhase": "PostEngineInit" } ], "Plugins": [ diff --git a/ProjectFish/Source/ProjectFish.Target.cs b/ProjectFish/Source/ProjectFish.Target.cs index 3c1a480..2cbd69d 100644 --- a/ProjectFish/Source/ProjectFish.Target.cs +++ b/ProjectFish/Source/ProjectFish.Target.cs @@ -11,5 +11,11 @@ public class ProjectFishTarget : TargetRules DefaultBuildSettings = BuildSettingsVersion.V5; IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_5; ExtraModuleNames.Add("ProjectFish"); + RegisterModulesCreatedByRider(); + } + + private void RegisterModulesCreatedByRider() + { + ExtraModuleNames.AddRange(new string[] { "ProjectFishEditor" }); } } diff --git a/ProjectFish/Source/ProjectFish/Definations.h b/ProjectFish/Source/ProjectFish/Definations.h index 5e379a0..c49fae6 100644 --- a/ProjectFish/Source/ProjectFish/Definations.h +++ b/ProjectFish/Source/ProjectFish/Definations.h @@ -130,6 +130,19 @@ struct FSkillData: public FTableRowBase UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ToolTip = "技能效果组")) TArray SkillEffects; }; + + +USTRUCT(BlueprintType) +struct FSkillDataConfig +{ + GENERATED_BODY() +public: + UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (RowType = "FSkillData")) + UDataTable* DataTable; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + FName SkillRowName; +}; /** * */ diff --git a/ProjectFish/Source/ProjectFishEditor.Target.cs b/ProjectFish/Source/ProjectFishEditor.Target.cs index d69b068..af75068 100644 --- a/ProjectFish/Source/ProjectFishEditor.Target.cs +++ b/ProjectFish/Source/ProjectFishEditor.Target.cs @@ -11,5 +11,11 @@ public class ProjectFishEditorTarget : TargetRules DefaultBuildSettings = BuildSettingsVersion.V5; IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_5; ExtraModuleNames.Add("ProjectFish"); + RegisterModulesCreatedByRider(); + } + + private void RegisterModulesCreatedByRider() + { + ExtraModuleNames.AddRange(new string[] { "ProjectFishEditor" }); } } diff --git a/ProjectFish/Source/ProjectFishEditor/Private/DataTableRowSelectorCustomization.cpp b/ProjectFish/Source/ProjectFishEditor/Private/DataTableRowSelectorCustomization.cpp new file mode 100644 index 0000000..96a7120 --- /dev/null +++ b/ProjectFish/Source/ProjectFishEditor/Private/DataTableRowSelectorCustomization.cpp @@ -0,0 +1,154 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "DataTableRowSelectorCustomization.h" + +#include "DetailLayoutBuilder.h" +#include "DetailWidgetRow.h" +#include "IDetailChildrenBuilder.h" +#include "IPropertyUtilities.h" +#include "AssetRegistry/AssetRegistryModule.h" +#include "ProjectFish/Definations.h" + + +void FDataTableRowSelectorCustomization::CustomizeHeader(TSharedRef PropertyHandle, + FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils) +{ + HeaderRow + .NameContent() + [ + PropertyHandle->CreatePropertyNameWidget() + ]; +} + +void FDataTableRowSelectorCustomization::CustomizeChildren(TSharedRef PropertyHandle, + IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& CustomizationUtils) +{ + //获取meta中的过滤类型 + DataTableHandle = PropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FSkillDataConfig, DataTable)); + FProperty* metaProperty = DataTableHandle->GetMetaDataProperty(); + AllowRowType = metaProperty->GetMetaData("RowType"); + TWeakPtr PropertyUtils = CustomizationUtils.GetPropertyUtilities(); + //动态生成DataTable下拉菜单 + RefreshDataTableAfterFilter(); + //获得默认的属性值 + UObject* CurrentValue = nullptr; + DataTableHandle->GetValue(CurrentValue); // 获取当前设置的 DataTable + SelectedDataTable = CurrentValue ? FName(CurrentValue->GetName()) : NAME_None; + //添加datatable 列表 + TSharedPtr> DataTableComboBox = SNew(SComboBox) + .OptionsSource(&FilteredDataTableNames) + .Content() + [ + SNew(STextBlock) + .Text_Lambda([this]() -> FText { + return FText::FromName(SelectedDataTable); + }) + ] + .OnGenerateWidget_Lambda([](FName InItem) + { + + UDataTable* dataTable = Cast(FSoftObjectPath(InItem.ToString()).TryLoad()); + return SNew(STextBlock) + .Text(FText::FromString(dataTable->GetName())); + }) + .OnSelectionChanged_Lambda([this, PropertyHandle, PropertyUtils, &DataTableComboBox, &ChildBuilder](FName SelectedTableName, ESelectInfo::Type SelectInfo) + { + UDataTable* dataTable = Cast(FSoftObjectPath(SelectedTableName.ToString()).TryLoad()); + DataTableHandle->SetValue(dataTable); + SelectedDataTable = FName(dataTable->GetName()); + + //更新行选择器 + GenerateRowNameSelecter( PropertyHandle, ChildBuilder); + PropertyUtils.Pin()->ForceRefresh(); + }); + + ChildBuilder.AddCustomRow(FText::FromString(TEXT("DataTable"))) + .NameContent() + [ SNew(STextBlock) + .Text(FText::FromString(TEXT("SkillDataTable"))) + .Font(IDetailLayoutBuilder::GetDetailFont()) + ] + .ValueContent() + [DataTableComboBox.ToSharedRef()]; + + //添加默认的row列表 + if (!SelectedDataTable.IsNone()) + { + GenerateRowNameSelecter( PropertyHandle, ChildBuilder); + } +} + +void FDataTableRowSelectorCustomization::RefreshDataTableAfterFilter() +{ + FilteredDataTableNames.Empty(); + FAssetRegistryModule& AssetRegistry = FModuleManager::LoadModuleChecked("AssetRegistry"); + TArray AllDataTables; + AssetRegistry.Get().GetAssetsByClass(UDataTable::StaticClass()->GetClassPathName(), AllDataTables); + //UEn内部存储是没有F的 + FString BaseName = AllowRowType.StartsWith("F") ? AllowRowType.Mid(1) : AllowRowType; + for (const FAssetData& Asset: AllDataTables) + { + FString RowStructPath = Asset.GetTagValueRef("RowStructure"); + if (RowStructPath.EndsWith(BaseName)) + { + FilteredDataTableNames.Add(FName(Asset.GetObjectPathString())); + //FilteredDataTables.Add(MakeShareable(Cast(FSoftObjectPath(Asset.GetObjectPathString()).TryLoad()))); + } + } +} + +void FDataTableRowSelectorCustomization::GenerateRowNameSelecter(TSharedRef PropertyHandle, IDetailChildrenBuilder& ChildBuilder) +{ + RowNameHandle = PropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FSkillDataConfig, SkillRowName)); + UObject* CurrentTable = nullptr; + DataTableHandle->GetValue(CurrentTable); + UDataTable* CurrentDataTable = Cast(CurrentTable); + + if (CurrentDataTable) + { + //获得默认的选中行 + FName defaultRowName; + RowNameHandle->GetValue(defaultRowName); + FSkillData* skillData = CurrentDataTable->FindRow(defaultRowName, ""); + if (skillData) + SelectedRowName = FName(skillData->SkillName.ToString()); + + DataTableRows = CurrentDataTable->GetRowNames(); + TSharedPtr> RowNameComboBox = SNew(SComboBox) + .OptionsSource(&DataTableRows) + .Content() + [ + SNew(STextBlock) + .Text_Lambda([this]() -> FText { + return FText::FromName(SelectedRowName); + }) + ] + .OnGenerateWidget_Lambda([this](FName rowName) { + UObject* CurrentTable = nullptr; + DataTableHandle->GetValue(CurrentTable); + UDataTable* CurrentDataTable = Cast(CurrentTable); + FSkillData* skillData = CurrentDataTable->FindRow(rowName, ""); + return SNew(STextBlock).Text(skillData->SkillName); + }) + .OnSelectionChanged_Lambda([&](FName SelectedDataTableName, ESelectInfo::Type) { + UObject* CurrentTable = nullptr; + DataTableHandle->GetValue(CurrentTable); + UDataTable* CurrentDataTable = Cast(CurrentTable); + FSkillData* skillData = CurrentDataTable->FindRow(SelectedDataTableName, ""); + SelectedRowName = FName(skillData->SkillName.ToString()); + RowNameHandle->SetValue(SelectedDataTableName); + }); + + ChildBuilder.AddCustomRow(FText::FromString(TEXT("Row"))) + .NameContent()[ + SNew(STextBlock) + .Text(FText::FromString(TEXT("SkillRowName"))) + .Font(IDetailLayoutBuilder::GetDetailFont()) + ] + .ValueContent()[ RowNameComboBox.ToSharedRef() ]; + } + + + +} diff --git a/ProjectFish/Source/ProjectFishEditor/Private/ProjectFishEditor.cpp b/ProjectFish/Source/ProjectFishEditor/Private/ProjectFishEditor.cpp new file mode 100644 index 0000000..ba9751b --- /dev/null +++ b/ProjectFish/Source/ProjectFishEditor/Private/ProjectFishEditor.cpp @@ -0,0 +1,25 @@ +#include "ProjectFishEditor.h" + +#include "DataTableRowSelectorCustomization.h" + +#define LOCTEXT_NAMESPACE "FProjectFishEditorModule" + +void FProjectFishEditorModule::StartupModule() +{ + FPropertyEditorModule& PropModule = FModuleManager::LoadModuleChecked("PropertyEditor"); + PropModule.RegisterCustomPropertyTypeLayout("SkillDataConfig" + , FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FDataTableRowSelectorCustomization::MakeInstance)); + +} + +void FProjectFishEditorModule::ShutdownModule() +{ + if ( FPropertyEditorModule* PropModule = FModuleManager::GetModulePtr("PropertyEditor")) + { + PropModule->UnregisterCustomPropertyTypeLayout("SkillDataConfig"); + } +} + +#undef LOCTEXT_NAMESPACE + +IMPLEMENT_MODULE(FProjectFishEditorModule, ProjectFishEditor) \ No newline at end of file diff --git a/ProjectFish/Source/ProjectFishEditor/ProjectFishEditor.Build.cs b/ProjectFish/Source/ProjectFishEditor/ProjectFishEditor.Build.cs new file mode 100644 index 0000000..1d1f241 --- /dev/null +++ b/ProjectFish/Source/ProjectFishEditor/ProjectFishEditor.Build.cs @@ -0,0 +1,28 @@ +using UnrealBuildTool; + +public class ProjectFishEditor : ModuleRules +{ + public ProjectFishEditor(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + OptimizeCode = CodeOptimization.Never; + PublicDependencyModuleNames.AddRange( + new string[] + { + "Core", + } + ); + + PrivateDependencyModuleNames.AddRange( + new string[] + { + "CoreUObject", + "Engine", + "Slate", + "SlateCore", + "ProjectFish", + "InputCore" + } + ); + } +} \ No newline at end of file diff --git a/ProjectFish/Source/ProjectFishEditor/Public/DataTableRowSelectorCustomization.h b/ProjectFish/Source/ProjectFishEditor/Public/DataTableRowSelectorCustomization.h new file mode 100644 index 0000000..aae662f --- /dev/null +++ b/ProjectFish/Source/ProjectFishEditor/Public/DataTableRowSelectorCustomization.h @@ -0,0 +1,32 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" + +/** + * + */ +class FDataTableRowSelectorCustomization: public IPropertyTypeCustomization +{ +public: + static TSharedRef MakeInstance() + { + return MakeShareable(new FDataTableRowSelectorCustomization()); + } + FDataTableRowSelectorCustomization(){} + virtual void CustomizeHeader(TSharedRef PropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils) override; + virtual void CustomizeChildren(TSharedRef PropertyHandle, IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& CustomizationUtils) override; +private: + void RefreshDataTableAfterFilter(); + void GenerateRowNameSelecter(TSharedRef PropertyHandle, IDetailChildrenBuilder& ChildBuilder); + + + TSharedPtr DataTableHandle; + FName SelectedDataTable = NAME_None; //选中的datatable + TSharedPtr RowNameHandle; + FName SelectedRowName = NAME_None;; //选中的row + TArray FilteredDataTableNames; + TArray DataTableRows; + FString AllowRowType; //dataTable过滤的行类型 +}; diff --git a/ProjectFish/Source/ProjectFishEditor/Public/ProjectFishEditor.h b/ProjectFish/Source/ProjectFishEditor/Public/ProjectFishEditor.h new file mode 100644 index 0000000..9669917 --- /dev/null +++ b/ProjectFish/Source/ProjectFishEditor/Public/ProjectFishEditor.h @@ -0,0 +1,11 @@ +#pragma once + +#include "CoreMinimal.h" +#include "Modules/ModuleManager.h" + +class FProjectFishEditorModule : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void ShutdownModule() override; +};