Details Panel 커스터마이징으로 작업 흐름 개선하기
24강. Details Panel 커스터마이징으로 작업 흐름 개선하기
1. 이번 강의에서 해결할 문제
설정 속성이 많아지면 사용자가 어떤 값을 먼저 입력해야 하는지, 현재 조합이 왜 위험한지 알기 어렵습니다. 하지만 Runtime 클래스 자체에 Editor Widget 코드를 넣으면 경계가 깨집니다. 표시 규칙은 Editor Module이 맡고 데이터 클래스는 Runtime 계약을 유지해야 합니다.
2. 학습 목표
3. 핵심 개념
Details Customization은 UObject 속성 자체를 바꾸는 기능이 아니라 Editor에서 표현·그룹화·추가 행동을 제공하는 계층입니다. PropertyEditor Module에 등록되며 Runtime 클래스는 이 존재를 몰라도 됩니다.
UI에서 값을 숨기거나 경고하는 것만으로 데이터가 안전해지는 것은 아닙니다. Commandlet, 자동 생성, 이전 버전 에셋은 UI를 거치지 않을 수 있으므로 26강의 Data Validation이 최종 검사 책임을 집니다.
4. 단계별 실습
#pragma once
#include "IDetailCustomization.h"
class FInteractionSettingsCustomization final
: public IDetailCustomization
{
public:
static TSharedRef<IDetailCustomization> MakeInstance();
virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override;
};
#include "Details/InteractionSettingsCustomization.h"
#include "DetailCategoryBuilder.h"
#include "DetailLayoutBuilder.h"
#include "DetailWidgetRow.h"
#include "Settings/InteractionSettings.h"
#include "Widgets/Text/STextBlock.h"
#define LOCTEXT_NAMESPACE "InteractionSettingsCustomization"
TSharedRef<IDetailCustomization>
FInteractionSettingsCustomization::MakeInstance()
{
return MakeShared<FInteractionSettingsCustomization>();
}
void FInteractionSettingsCustomization::CustomizeDetails(
IDetailLayoutBuilder& DetailBuilder)
{
TSharedRef<IPropertyHandle> Distance =
DetailBuilder.GetProperty(
GET_MEMBER_NAME_CHECKED(
UInteractionSettings, DefaultTraceDistance));
IDetailCategoryBuilder& Diagnostics =
DetailBuilder.EditCategory("Diagnostics");
Diagnostics.AddCustomRow(LOCTEXT("DistanceHelpSearch", "Trace Distance"))
.WholeRowContent()
[
SNew(STextBlock)
.Text(LOCTEXT(
"DistanceHelp",
"Keep the default distance small enough to avoid ambiguous targets."))
.AutoWrapText(true)
];
Distance->SetOnPropertyValueChanged(
FSimpleDelegate::CreateLambda([]
{
UE_LOG(LogTemp, Verbose,
TEXT("Interaction trace distance changed"));
}));
}
#undef LOCTEXT_NAMESPACE
Editor Module에서 등록합니다.
#include "Details/InteractionSettingsCustomization.h"
#include "PropertyEditorModule.h"
void FDataGuardEditorModule::RegisterDetails()
{
FPropertyEditorModule& PropertyEditor =
FModuleManager::LoadModuleChecked<FPropertyEditorModule>(
"PropertyEditor");
PropertyEditor.RegisterCustomClassLayout(
"InteractionSettings",
FOnGetDetailCustomizationInstance::CreateStatic(
&FInteractionSettingsCustomization::MakeInstance));
PropertyEditor.NotifyCustomizationModuleChanged();
}
void FDataGuardEditorModule::UnregisterDetails()
{
if (FModuleManager::Get().IsModuleLoaded("PropertyEditor"))
{
FPropertyEditorModule& PropertyEditor =
FModuleManager::GetModuleChecked<FPropertyEditorModule>(
"PropertyEditor");
PropertyEditor.UnregisterCustomClassLayout(
"InteractionSettings");
PropertyEditor.NotifyCustomizationModuleChanged();
}
}
PropertyEditor는 DataGuardEditor의 Private Dependency입니다. Class Layout 이름은 U 접두어를 제외한 Reflection 이름을 사용합니다.
5. 코드가 동작하는 이유
PropertyEditor가 InteractionSettings 객체를 표시할 때 등록된 Factory로 Customization 인스턴스를 만듭니다. Editor Module이 Runtime 클래스를 읽는 단방향 관계이므로 Runtime Package에는 Details 코드가 포함되지 않습니다. Property Handle은 Undo/Redo와 다중 선택 같은 Editor 속성 흐름을 보존합니다.
6. 자주 하는 실수와 해결법
7. 직접 실습
8. 이해 점검 질문 3개
9. 핵심 요약
Details Panel 커스터마이징으로 작업 흐름 개선하기 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.