添加自定义datatable属性面板
This commit is contained in:
parent
377eff645b
commit
54ba19f832
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -8,6 +8,11 @@
|
|||||||
"Name": "ProjectFish",
|
"Name": "ProjectFish",
|
||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "Default"
|
"LoadingPhase": "Default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "ProjectFishEditor",
|
||||||
|
"Type": "Editor",
|
||||||
|
"LoadingPhase": "PostEngineInit"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Plugins": [
|
"Plugins": [
|
||||||
|
@ -11,5 +11,11 @@ public class ProjectFishTarget : TargetRules
|
|||||||
DefaultBuildSettings = BuildSettingsVersion.V5;
|
DefaultBuildSettings = BuildSettingsVersion.V5;
|
||||||
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_5;
|
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_5;
|
||||||
ExtraModuleNames.Add("ProjectFish");
|
ExtraModuleNames.Add("ProjectFish");
|
||||||
|
RegisterModulesCreatedByRider();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterModulesCreatedByRider()
|
||||||
|
{
|
||||||
|
ExtraModuleNames.AddRange(new string[] { "ProjectFishEditor" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,6 +130,19 @@ struct FSkillData: public FTableRowBase
|
|||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ToolTip = "技能效果组"))
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ToolTip = "技能效果组"))
|
||||||
TArray<FSkillEffectData> SkillEffects;
|
TArray<FSkillEffectData> SkillEffects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType)
|
||||||
|
struct FSkillDataConfig
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (RowType = "FSkillData"))
|
||||||
|
UDataTable* DataTable;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||||
|
FName SkillRowName;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -11,5 +11,11 @@ public class ProjectFishEditorTarget : TargetRules
|
|||||||
DefaultBuildSettings = BuildSettingsVersion.V5;
|
DefaultBuildSettings = BuildSettingsVersion.V5;
|
||||||
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_5;
|
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_5;
|
||||||
ExtraModuleNames.Add("ProjectFish");
|
ExtraModuleNames.Add("ProjectFish");
|
||||||
|
RegisterModulesCreatedByRider();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterModulesCreatedByRider()
|
||||||
|
{
|
||||||
|
ExtraModuleNames.AddRange(new string[] { "ProjectFishEditor" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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<IPropertyHandle> PropertyHandle,
|
||||||
|
FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils)
|
||||||
|
{
|
||||||
|
HeaderRow
|
||||||
|
.NameContent()
|
||||||
|
[
|
||||||
|
PropertyHandle->CreatePropertyNameWidget()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDataTableRowSelectorCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> PropertyHandle,
|
||||||
|
IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& CustomizationUtils)
|
||||||
|
{
|
||||||
|
//获取meta中的过滤类型
|
||||||
|
DataTableHandle = PropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FSkillDataConfig, DataTable));
|
||||||
|
FProperty* metaProperty = DataTableHandle->GetMetaDataProperty();
|
||||||
|
AllowRowType = metaProperty->GetMetaData("RowType");
|
||||||
|
TWeakPtr<IPropertyUtilities> PropertyUtils = CustomizationUtils.GetPropertyUtilities();
|
||||||
|
//动态生成DataTable下拉菜单
|
||||||
|
RefreshDataTableAfterFilter();
|
||||||
|
//获得默认的属性值
|
||||||
|
UObject* CurrentValue = nullptr;
|
||||||
|
DataTableHandle->GetValue(CurrentValue); // 获取当前设置的 DataTable
|
||||||
|
SelectedDataTable = CurrentValue ? FName(CurrentValue->GetName()) : NAME_None;
|
||||||
|
//添加datatable 列表
|
||||||
|
TSharedPtr<SComboBox<FName>> DataTableComboBox = SNew(SComboBox<FName>)
|
||||||
|
.OptionsSource(&FilteredDataTableNames)
|
||||||
|
.Content()
|
||||||
|
[
|
||||||
|
SNew(STextBlock)
|
||||||
|
.Text_Lambda([this]() -> FText {
|
||||||
|
return FText::FromName(SelectedDataTable);
|
||||||
|
})
|
||||||
|
]
|
||||||
|
.OnGenerateWidget_Lambda([](FName InItem)
|
||||||
|
{
|
||||||
|
|
||||||
|
UDataTable* dataTable = Cast<UDataTable>(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<UDataTable>(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<FAssetRegistryModule>("AssetRegistry");
|
||||||
|
TArray<FAssetData> 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<FString>("RowStructure");
|
||||||
|
if (RowStructPath.EndsWith(BaseName))
|
||||||
|
{
|
||||||
|
FilteredDataTableNames.Add(FName(Asset.GetObjectPathString()));
|
||||||
|
//FilteredDataTables.Add(MakeShareable(Cast<UDataTable>(FSoftObjectPath(Asset.GetObjectPathString()).TryLoad())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FDataTableRowSelectorCustomization::GenerateRowNameSelecter(TSharedRef<IPropertyHandle> PropertyHandle, IDetailChildrenBuilder& ChildBuilder)
|
||||||
|
{
|
||||||
|
RowNameHandle = PropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FSkillDataConfig, SkillRowName));
|
||||||
|
UObject* CurrentTable = nullptr;
|
||||||
|
DataTableHandle->GetValue(CurrentTable);
|
||||||
|
UDataTable* CurrentDataTable = Cast<UDataTable>(CurrentTable);
|
||||||
|
|
||||||
|
if (CurrentDataTable)
|
||||||
|
{
|
||||||
|
//获得默认的选中行
|
||||||
|
FName defaultRowName;
|
||||||
|
RowNameHandle->GetValue(defaultRowName);
|
||||||
|
FSkillData* skillData = CurrentDataTable->FindRow<FSkillData>(defaultRowName, "");
|
||||||
|
if (skillData)
|
||||||
|
SelectedRowName = FName(skillData->SkillName.ToString());
|
||||||
|
|
||||||
|
DataTableRows = CurrentDataTable->GetRowNames();
|
||||||
|
TSharedPtr<SComboBox<FName>> RowNameComboBox = SNew(SComboBox<FName>)
|
||||||
|
.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<UDataTable>(CurrentTable);
|
||||||
|
FSkillData* skillData = CurrentDataTable->FindRow<FSkillData>(rowName, "");
|
||||||
|
return SNew(STextBlock).Text(skillData->SkillName);
|
||||||
|
})
|
||||||
|
.OnSelectionChanged_Lambda([&](FName SelectedDataTableName, ESelectInfo::Type) {
|
||||||
|
UObject* CurrentTable = nullptr;
|
||||||
|
DataTableHandle->GetValue(CurrentTable);
|
||||||
|
UDataTable* CurrentDataTable = Cast<UDataTable>(CurrentTable);
|
||||||
|
FSkillData* skillData = CurrentDataTable->FindRow<FSkillData>(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() ];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
#include "ProjectFishEditor.h"
|
||||||
|
|
||||||
|
#include "DataTableRowSelectorCustomization.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "FProjectFishEditorModule"
|
||||||
|
|
||||||
|
void FProjectFishEditorModule::StartupModule()
|
||||||
|
{
|
||||||
|
FPropertyEditorModule& PropModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
|
||||||
|
PropModule.RegisterCustomPropertyTypeLayout("SkillDataConfig"
|
||||||
|
, FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FDataTableRowSelectorCustomization::MakeInstance));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FProjectFishEditorModule::ShutdownModule()
|
||||||
|
{
|
||||||
|
if ( FPropertyEditorModule* PropModule = FModuleManager::GetModulePtr<FPropertyEditorModule>("PropertyEditor"))
|
||||||
|
{
|
||||||
|
PropModule->UnregisterCustomPropertyTypeLayout("SkillDataConfig");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|
||||||
|
IMPLEMENT_MODULE(FProjectFishEditorModule, ProjectFishEditor)
|
@ -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"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -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<IPropertyTypeCustomization> MakeInstance()
|
||||||
|
{
|
||||||
|
return MakeShareable(new FDataTableRowSelectorCustomization());
|
||||||
|
}
|
||||||
|
FDataTableRowSelectorCustomization(){}
|
||||||
|
virtual void CustomizeHeader(TSharedRef<IPropertyHandle> PropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils) override;
|
||||||
|
virtual void CustomizeChildren(TSharedRef<IPropertyHandle> PropertyHandle, IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& CustomizationUtils) override;
|
||||||
|
private:
|
||||||
|
void RefreshDataTableAfterFilter();
|
||||||
|
void GenerateRowNameSelecter(TSharedRef<IPropertyHandle> PropertyHandle, IDetailChildrenBuilder& ChildBuilder);
|
||||||
|
|
||||||
|
|
||||||
|
TSharedPtr<IPropertyHandle> DataTableHandle;
|
||||||
|
FName SelectedDataTable = NAME_None; //选中的datatable
|
||||||
|
TSharedPtr<IPropertyHandle> RowNameHandle;
|
||||||
|
FName SelectedRowName = NAME_None;; //选中的row
|
||||||
|
TArray<FName> FilteredDataTableNames;
|
||||||
|
TArray<FName> DataTableRows;
|
||||||
|
FString AllowRowType; //dataTable过滤的行类型
|
||||||
|
};
|
@ -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;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user