// 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() ]; } }