Copy IDetailPropertyRow* Row = <IDetailCategoryBuilder variable>.AddExternalObjectProperty({InObject}, PropertyName)
Copy GET_MEMBER_NAME_CHECKED(<Class>, <Variable Name>)
If the variable is protected or private, use the string property name.
Copy Row.DisplayName(FText::FromString(VariableOverrideName));
To add it to a group rather than a category, generate the category row first, and then hide that row and use the property handle from the row to generate a new property row in the group.
Copy Row->Visibility(EVisibility::Collapsed);
IDetailPropertyRow& NewGroupRow = NewGroup.AddPropertyRow(Row->GetPropertyHandle().ToSharedRef());
The Display Name can be set the same as above with the new group-generated row.
Copy TArray<UBoxComponent*> Killboxes = Settings->GetParentWaterfall()->GetAllKillboxes();
for (UBoxComponent* KillBox : Killboxes)
{
IDetailGroup& NewGroup = Cat_Kill.AddGroup(KillBox->GetFName(), FText::FromString(FName::NameToDisplayString(KillBox->GetName(), false)));
auto AddExternalPropertyToKillGroup = [&](FName PropertyName, FString VariableOverrideName = "")
{
IDetailPropertyRow* Row = Cat_Kill.AddExternalObjectProperty({ KillBox }, PropertyName);
if (Row)
{
Row->Visibility(EVisibility::Collapsed);
IDetailPropertyRow& NewGroupRow = NewGroup.AddPropertyRow(Row->GetPropertyHandle().ToSharedRef());
if (!VariableOverrideName.IsEmpty()) NewGroupRow.DisplayName(FText::FromString(VariableOverrideName));
}
};
AddExternalPropertyToKillGroup(USceneComponent::GetRelativeLocationPropertyName(), "Location");
AddExternalPropertyToKillGroup(USceneComponent::GetRelativeRotationPropertyName(), "Rotation");
AddExternalPropertyToKillGroup(USceneComponent::GetRelativeScale3DPropertyName(), "Scale");
AddExternalPropertyToKillGroup("BoxExtent", "Extent");
}