添加自定义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",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default"
|
||||
},
|
||||
{
|
||||
"Name": "ProjectFishEditor",
|
||||
"Type": "Editor",
|
||||
"LoadingPhase": "PostEngineInit"
|
||||
}
|
||||
],
|
||||
"Plugins": [
|
||||
|
@ -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" });
|
||||
}
|
||||
}
|
||||
|
@ -130,6 +130,19 @@ struct FSkillData: public FTableRowBase
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ToolTip = "技能效果组"))
|
||||
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;
|
||||
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_5;
|
||||
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