특정 편집 조건에 따라 디테일(Details) 패널에서 프로퍼티 필드나 기타 UI 요소를 선택적으로 표시하거나 숨기거나 비활성화해야 할 수 있습니다. 예를 들어, 프로젝트 세팅(Project Setting)의 폰트 해상도(Font Resolution) 세팅에는 드롭다운 필드가 있어 프리셋 DPI 값을 선택할 수 있지만, 커스텀 DPI 사용(Use Custom DPI) 세팅을 체크하면 정수 필드가 대신 표시됩니다.
언리얼 엔진(UE)에서는 몇 가지 방식으로 디테일 뷰에서 커스텀 편집 조건을 처리할 수 있습니다. 이 문서에서는 슬레이트 C++ 코드의 UPROPERTY 구현과 커스텀 편집 조건에 대한 레퍼런스를 제공합니다.
전제조건
이 페이지에서는 디테일 패널 커스터마이제이션 퀵스타트 튜토리얼에 기반한 예시를 보여주며 다음을 참조합니다.
- FCustomDataProperty – 다음으로 구성된 커스텀 구조체입니다.
- TSoftObjectPtr
CustomTexture - FName CustomName
- FString CustomString
- Int32 CustomInt
- TSoftObjectPtr
- ACustomActor – 다음과 같은 프로퍼티가 추가된 단순한 액터입니다.
- TSoftObjectPtr
CustomMesh - float CustomFloat
- bool CustomBool
- FCustomDataProperty CustomData
- TSoftObjectPtr
-
FCustomDataPropertyCustomization – FCustomDataProperty에 대한 프로퍼티 타입 커스터마이제이션입니다.
- FCustomClassDetailsCustomization – ACustomActor에 대한 디테일 커스터마이제이션입니다.
UPROPERTY 메타데이터의 편집 조건
프로퍼티의 UPROPERTY 메타데이터를 사용하여 EditCondition 태그로 커스텀 편집 조건을 지정할 수 있습니다. 편집 조건은 편집 조건 역할을 하는 함수 또는 필드 이름이 포함된 스트링이어야 합니다.
UPROPERTY(EditAnywhere)
bool bAllowEdit;
UPROPERTY(EditAnywhere, meta = (DisplayName = "Custom Integer", EditCondition = "bAllowEdit"))
uint32 CustomInt;
편집 조건이 충족되지 않으면 프로퍼티가 비활성화됩니다.
편집 조건의 연산자
EditCondition 태그에서 연산자를 사용하여 더 복잡한 기준을 제공할 수 있습니다. 몇 가지 예를 들면 다음과 같습니다.
- NOT EQUAL 연산자인
!=연산자를 사용하면 부울 값이true가 아닐 때 편집을 허용할 수 있습니다. >,>=,<및<=연산자를 사용하면 변수가 특정 한계치 내에 있을 때 편집을 허용할 수 있습니다.- AND 연산자인
&&연산자를 사용하면 여러 편집 조건을 하나로 묶을 수 있습니다. - OR 연산자인
||연산자를 사용하면 대체 편집 조건을 제공할 수 있습니다.
위의 목록은 연산자의 전부가 아니지만, 흔히 사용되는 몇 가지 대표적인 논리 연산자와 비교 연산자입니다. 다음은 이러한 연산자 중 몇 가지의 사용 사례입니다.
CustomActor.h
UPROPERTY(EditAnywhere)
bool bRestrictEdit;
// bRestrictEdit가 true가 아닐 때만 CustomInt를 편집할 수 있습니다.
UPROPERTY(EditAnywhere, meta = (DisplayName = "Custom Integer", EditCondition = "!bRestrictEdit"))
uint32 CustomInt;
//CustomInt가 10~20이고 bRestrictEdit가 false일 때만 CustomFloat를 편집할 수 있습니다.
UPROPERTY(EditAnywhere, meta=(DisplayName = "Custom Float", EditCondition = "CustomInt > 10 && CustomInt < 20 && !bRestrictEdit"))
Float CustomFloat;
또한, == 연산자를 사용하여 특정 값이 충족되는지를 확인할 수도 있습니다. 이는 열거형을 편집 조건으로 사용할 때 유용합니다.
CustomActor.h
UPROPERTY(EditAnywhere)
ECustomIntEditMode EditMode;
// EditMode가 AllowEdit일 때만 CustomInt를 편집할 수 있습니다.
UPROPERTY(EditAnywhere, meta = (DisplayName = "Custom Integer", EditCondition = "EditMode==ECustomIntEditMode::AllowEdt"))
uint32 CustomInt;
UPROPERTY 편집 조건의 함수
현재 UPROPERTY 편집 조건은 함수 사용을 지원하지 않습니다. 함수 또는 델리게이트를 편집 조건의 기반으로 사용해야 한다면, 아래에 나온 디테일 패널 커스터마이제이션의 커스텀 편집 조건 섹션을 참조하세요.
EditConditionHides
EditConditionHides 메타데이터 태그를 사용하여 프로퍼티 필드를 비활성화할 수 있을 뿐 아니라 해당 편집 조건이 충족되지 않을 때 필드를 숨길 수도 있습니다.
이 메서드는 앞서 언급한 폰트 해상도 세팅에 사용됩니다. C++ 코드에서 UUserInterfaceSettings 에는 실제로 폰트 DPI 처리를 위한 다음과 같은 세 가지 변수가 포함되어 있습니다.
- 드롭다운의 프리셋을 나타내는
FontDPIPreset이라는EFontDPI열거형 - 편집할 수 있는 정수 필드를 나타내는
CustomFontDPI라는uint32 - 위의 두 변수에 대한 EditCondition에 사용되는
bUseCustomFontDPI라는 boolean
CustomClassDetailsCustomization.h
#if WITH_EDITORONLY_DATA
/**
* UMG 폰트 크기와 픽셀 높이 간 관계를 제어합니다.
*/
UPROPERTY(config, EditAnywhere, Category = "UMG Fonts", meta = (DisplayName = "Font Resolution", EditCondition = "bUseCustomFontDPI", EditConditionHides, ClampMin = "1", ClampMax = "1000"))
uint32 CustomFontDPI;
/**
* UMG 폰트 크기와 픽셀 높이 간 관계를 제어합니다.
*/
UPROPERTY(config, EditAnywhere, Category = "UMG Fonts", meta = (DisplayName = "Font Resolution", EditCondition = "!bUseCustomFontDPI", EditConditionHides))
EFontDPI FontDPIPreset;
/**
* 커스텀 값을 설정하려면 이 박스를 체크한 다음 텍스트 박스에 값을 입력합니다.
*/
UPROPERTY(config, EditAnywhere, Category = "UMG Fonts", meta = (DisplayName = "Use Custom DPI"))
bool bUseCustomFontDPI;
#endif
또한 UUserInterfaceSettings 는 폰트 DPI 계산에 bUseCustomFontDPI 를 사용하여 CustomFontDPI 값을 그대로 사용할지 FontDPIPreset을 정수 값으로 변환할지 선택합니다.
CustomFontDPI 프로퍼티의 EditCondition 은 "bUseCustomFontDPI" 를 그대로 사용하므로 bUseCustomFontDPI 가 true여야 CustomFontDPI 가 표시되고 사용됩니다.
한편, FontDPIPreset 프로퍼티의 EditCondition 은 "!bUseCustomFontDPI" 입니다. ! 연산자가 있으므로 bUseCustomFontDPI가 false여야 FontDPIPreset 이 표시되고 사용된다는 뜻입니다.
InlineEditConditionToggle
UPROPERTY 메타데이터 태그 InlineEditConditionToggle 은 프로퍼티의 필드 옆에 활성화 또는 비활성화할 수 있는 체크 박스를 제공합니다. 이는 렌더링의 포스트 프로세싱 필드와 비슷하게 작동합니다.
// CustomInt 바로 옆에 활성화 및 비활성화를 위한 토글 필드가 표시됩니다.
UPROPERTY(EditAnywhere, meta = (DisplayName = "Custom Integer", InlineEditConditionToggle))
uint32 CustomInt;
여기서는 EditCondition 메타데이터 태그를 사용하지 않으며, InlineEditConditionToggle 은 자체 토글 필드를 제공하고 추적합니다.
디테일 패널 커스터마이제이션의 커스텀 편집 조건
디테일 패널 커스터마이제이션을 사용하여 더 복잡하거나 함수에 의존하는 편집 조건을 생성할 수 있습니다. 아래 예시에서는 프로퍼티 필드와 슬레이트 위젯에 대해 이러한 편집 조건을 생성하는 방법을 보여줍니다.
프로퍼티 필드에 대한 커스텀 편집 조건
프로퍼티 필드에 대한 커스텀 편집 조건을 생성하는 방법은 다음과 같습니다.
-
새로고침을 트리거할 프로퍼티를 사용하여 디테일 패널을 새로고침할 수 있는 델리게이트를 등록합니다. 이 프로세스에 대한 자세한 내용은 디테일 패널 새로 고치기를 참조하세요.
-
필요한 경우,
TSharedRef::Get및IPropertyHandle::GetValue를 사용하여 프로퍼티 값을 얻습니다. -
해당 값에 따라 프로퍼티를 추가하거나 숨깁니다. 자세한 내용은 프로퍼티 순서 변경 및 숨기기를 참조하세요.
CustomClassDetailsCustomization.h
bool boolValue; boolPropertyHandle.Get().GetValue(boolValue); if (boolValue) { DetailBuilder.AddProperty(GET_MEMBER_NAME_CHECKED(ACustomActor, CustomMesh)); } else { CustomCategory.HideProperty(GET_MEMBER_NAME_CHECKED(ACustomActor, CustomMesh)); }
또는 다른 함수를 작성하여 프로퍼티를 표시하고 숨기는 로직 또는 디테일 패널의 일부를 빌드하는 액션을 캡슐화하거나, 두 가지 모두를 캡슐화할 수 있습니다. IDetailLayoutBuilder 레퍼런스를 디테일 패널의 일부를 빌드하려는 함수의 파라미터로 제공합니다. 프로퍼티 핸들 레퍼런스 또는 프로퍼티 값을 이러한 항목을 고려하려는 함수의 파라미터로 제공합니다.
다음은 boolean을 TSoftPtr<UStaticMesh> 프로퍼티의 편집 조건으로 사용하고 디테일 패널을 새로 고치기 위한 델리게이트를 사용하는 CustomizeDetails 함수의 전체 예시입니다.
CustomClassDetailsCustomization.cpp
void FCustomClassDetailsCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
{
// 커스텀 세팅 카테고리를 추가합니다.
IDetailCategoryBuilder& CustomCategory = DetailBuilder.EditCategory(FName("Custom Settings"));
// 커스텀 세팅에 CustomBool 프로퍼티를 추가합니다.
CustomCategory.AddProperty(GET_MEMBER_NAME_CHECKED(ACustomActor, CustomBool));
// CustomBool에 대한 프로퍼티 핸들을 가져옵니다.
TSharedRef<IPropertyHandle> boolPropertyHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(ACustomActor, CustomBool));
// 값을 변경하기 위한 델리게이트를 구성합니다. 디테일 패널의 강제 새로고침을 트리거하려는 변수에 대한 프로퍼티 핸들에 이 델리게이트를 추가합니다.
const FSimpleDelegate OnValueChanged = FSimpleDelegate::CreateLambda([&DetailBuilder](){
DetailBuilder.ForceRefreshDetails();
});
// CustomBool의 프로퍼티 핸들에 프로퍼티 값 변경 델리게이트를 추가합니다.
boolPropertyHandle->SetOnPropertyValueChanged(OnValueChanged);
// 프로퍼티 핸들에서 CustomBool 값을 가져옵니다.
bool boolValue;
boolPropertyHandle.Get().GetValue(boolValue);
// CustomBool이 true면 CustomMesh 프로퍼티를 표시합니다. CustomBool이 false면 CustomMesh 프로퍼티를 숨깁니다.
if (boolValue)
{
DetailBuilder.AddProperty(GET_MEMBER_NAME_CHECKED(ACustomActor, CustomMesh));
}
else
{
CustomCategory.HideProperty(GET_MEMBER_NAME_CHECKED(ACustomActor, CustomMesh));
}
}
슬레이트 위젯에 대한 커스텀 편집 조건
디테일 패널 커스터마이제이션에서 더 복잡한 커스텀 슬레이트 위젯을 위한 편집 조건을 생성해야 할 수 있습니다. 예를 들어, 문서 액터(Documentation Actor) 의 도움말 URL 열기(Open Help URL) 버튼은 사용자가 문서 링크(Document Link) 필드를 채울 때까지 비활성화됩니다.
DocumentationActorDetails.cpp 는 도움말 URL 열기 버튼을 커스텀 행에 SButton 으로 추가합니다. FDocumentationActorDetails::IsButtonEnabled 는 IsEnabled 파라미터를 사용하여 버튼 활성화 여부를 제어합니다.
DocumentationActorDetails.cpp
// 클릭하여 문서를 열 수 있는 버튼을 추가합니다.
IDetailCategoryBuilder& HelpCategory = DetailBuilder.EditCategory("Help Data");
HelpCategory.AddCustomRow(LOCTEXT("HelpDocumentation_Filter", "Help Documentation"))
[
SNew(SButton)
.Text(this, &FDocumentationActorDetails::OnGetButtonText)
.ToolTipText(this, &FDocumentationActorDetails::OnGetButtonTooltipText)
.HAlign(HAlign_Center)
.OnClicked(this, &FDocumentationActorDetails::OnHelpButtonClicked)
.IsEnabled(this, &FDocumentationActorDetails::IsButtonEnabled)
];
FDocumentationActorDetails::IsButtonEnabled 는 유효한 문서 링크가 있는지에 따라 true 또는 false를 반환합니다.
DocumentationActorDetails.cpp
bool FDocumentationActorDetails::IsButtonEnabled() const
{
bool bResult = false;
if ((SelectedDocumentationActor.IsValid() == true) && (SelectedDocumentationActor->HasValidDocumentLink() == true))
{
EDocumentationActorType::Type LinkType = SelectedDocumentationActor->GetLinkType();
bResult = ((LinkType == EDocumentationActorType::UDNLink) || (LinkType == EDocumentationActorType::URLLink)) ? true : false;
}
return bResult;
}
이 구현으로 IsEnabled 슬레이트 파라미터를 할당하는 과정에서 자동으로 필요한 델리게이트와 응답이 추가되므로, 디테일 패널을 새로 고치기 위한 추가 프로그래밍은이 필요하지 않습니다.