void FPrimitiveComponentDetails::CustomizeDetails( IDetailLayoutBuilder& DetailBuilder ) { // Get the objects being customized so we can enable/disable editing of 'Simulate Physics' DetailBuilder.GetObjectsBeingCustomized(ObjectsCustomized); // See if we are hiding Physics category TArray<FString> HideCategories; FEditorCategoryUtils::GetClassHideCategories(DetailBuilder.GetDetailsView().GetBaseClass(), HideCategories); if(!HideCategories.Contains("Materials")) { AddMaterialCategory(DetailBuilder); } TSharedRef<IPropertyHandle> MobilityHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UPrimitiveComponent, Mobility), USceneComponent::StaticClass()); MobilityHandle->SetToolTipText(LOCTEXT("PrimitiveMobilityTooltip", "Mobility for primitive components controls how they can be modified in game and therefore how they interact with lighting and physics.\n● A movable primitive component can be changed in game, but requires dynamic lighting and shadowing from lights which have a large performance cost.\n● A static primitive component can't be changed in game, but can have its lighting baked, which allows rendering to be very efficient.")); if(!HideCategories.Contains("Physics")) { AddPhysicsCategory(DetailBuilder); } if (!HideCategories.Contains("Collision")) { AddCollisionCategory(DetailBuilder); } if(!HideCategories.Contains("Lighting")) { AddLightingCategory(DetailBuilder); } AddAdvancedSubCategory( DetailBuilder, "Rendering", "TextureStreaming" ); AddAdvancedSubCategory( DetailBuilder, "Rendering", "LOD"); }
void FPrimitiveComponentDetails::CustomizeDetails( IDetailLayoutBuilder& DetailBuilder ) { TSharedRef<IPropertyHandle> MobilityHandle = DetailBuilder.GetProperty("Mobility", USceneComponent::StaticClass()); MobilityHandle->SetToolTipText(LOCTEXT("PrimitiveMobilityTooltip", "Mobility for primitive components controls how they can be modified in game and therefore how they interact with lighting and physics.\n● A movable primitive component can be changed in game, but requires dynamic lighting and shadowing from lights which have a large performance cost.\n● A static primitive component can't be changed in game, but can have its lighting baked, which allows rendering to be very efficient.").ToString()); if ( DetailBuilder.GetProperty("BodyInstance")->IsValidHandle() ) { TSharedPtr<IPropertyHandle> BodyInstanceHandler = DetailBuilder.GetProperty("BodyInstance"); uint32 NumChildren = 0; BodyInstanceHandler->GetNumChildren(NumChildren); // See if we are hiding Physics category TArray<FString> HideCategories; FEditorCategoryUtils::GetClassHideCategories(DetailBuilder.GetDetailsView().GetBaseClass(), HideCategories); if (!HideCategories.Contains(TEXT("Physics"))) { IDetailCategoryBuilder& PhysicsCategory = DetailBuilder.EditCategory("Physics"); // Get the objects being customized so we can enable/disable editing of 'Simulate Physics' DetailBuilder.GetObjectsBeingCustomized(ObjectsCustomized); bool bDisplayMass = true; bool bDisplayMassOverride = true; for (int32 i = 0; i < ObjectsCustomized.Num(); ++i) { if (ObjectsCustomized[i].IsValid() && ObjectsCustomized[i]->IsA(UDestructibleComponent::StaticClass())) { bDisplayMass = false; bDisplayMassOverride = false; } if (ObjectsCustomized[i].IsValid() && ObjectsCustomized[i]->IsA(USkeletalMeshComponent::StaticClass())) { bDisplayMassOverride = false; } } // add all physics properties now - after adding mass for (uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex) { TSharedPtr<IPropertyHandle> ChildProperty = BodyInstanceHandler->GetChildHandle(ChildIndex); FString Category = FObjectEditorUtils::GetCategory(ChildProperty->GetProperty()); FString PropName = ChildProperty->GetProperty()->GetName(); if (Category == TEXT("Physics")) { // Only permit modifying bSimulatePhysics when the body has some geometry. if (PropName == TEXT("bSimulatePhysics")) { PhysicsCategory.AddProperty(ChildProperty).EditCondition(TAttribute<bool>(this, &FPrimitiveComponentDetails::IsSimulatePhysicsEditable), NULL); } else if (PropName == TEXT("bUseAsyncScene")) { //we only enable bUseAsyncScene if the project uses an AsyncScene PhysicsCategory.AddProperty(ChildProperty).EditCondition(TAttribute<bool>(this, &FPrimitiveComponentDetails::IsUseAsyncEditable), NULL); } else if (PropName == TEXT("LockedAxisMode")) { LockedAxisProperty = ChildProperty; PhysicsCategory.AddProperty(ChildProperty); } else if (PropName == TEXT("CustomLockedAxis")) { //we only enable bUseAsyncScene if the project uses an AsyncScene PhysicsCategory.AddProperty(ChildProperty).Visibility(TAttribute<EVisibility>(this, &FPrimitiveComponentDetails::IsCustomLockedAxisSelected)); } else if (PropName == TEXT("bAutoWeld")) { PhysicsCategory.AddProperty(ChildProperty).Visibility(TAttribute<EVisibility>(this, &FPrimitiveComponentDetails::IsAutoWeldVisible)) .EditCondition(TAttribute<bool>(this, &FPrimitiveComponentDetails::IsAutoWeldEditable), NULL); } else if (PropName == TEXT("bOverrideMass")) { if (bDisplayMassOverride) { PhysicsCategory.AddProperty(ChildProperty); } } else if (PropName == TEXT("MassInKg")) { if (bDisplayMass) { PhysicsCategory.AddCustomRow(TEXT("Mass"), false) .IsEnabled(TAttribute<bool>(this, &FPrimitiveComponentDetails::IsBodyMassEnabled)) .NameContent() [ ChildProperty->CreatePropertyNameWidget() ] .ValueContent() [ SNew(SVerticalBox) + SVerticalBox::Slot() .AutoHeight() [ SNew(SEditableTextBox) .Text(this, &FPrimitiveComponentDetails::OnGetBodyMass) .IsReadOnly(this, &FPrimitiveComponentDetails::IsBodyMassReadOnly) .Font(IDetailLayoutBuilder::GetDetailFont()) .Visibility(this, &FPrimitiveComponentDetails::IsMassVisible, false) ] + SVerticalBox::Slot() .AutoHeight() [ SNew(SVerticalBox) .Visibility(this, &FPrimitiveComponentDetails::IsMassVisible, true) + SVerticalBox::Slot() .AutoHeight() [ ChildProperty->CreatePropertyValueWidget() ] ] ]; } } else { PhysicsCategory.AddProperty(ChildProperty); } } } } // Collision { IDetailCategoryBuilder& CollisionCategory = DetailBuilder.EditCategory("Collision"); // add all collision properties for (uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex) { TSharedPtr<IPropertyHandle> ChildProperty = BodyInstanceHandler->GetChildHandle(ChildIndex); FString Category = FObjectEditorUtils::GetCategory(ChildProperty->GetProperty()); if (Category == TEXT("Collision")) { CollisionCategory.AddProperty(ChildProperty); } } } } AddAdvancedSubCategory( DetailBuilder, "Rendering", "TextureStreaming" ); AddAdvancedSubCategory( DetailBuilder, "Rendering", "LOD"); }