特定の編集条件に基づいて、[Details (詳細)] パネルのプロパティのフィールドやその他の UI 要素の表示/非表示を選択的に切り替えたり、無効にしたりする必要がある場合があります。たとえば、[Project Settings (プロジェクト設定)] の [Font Resolution (フォント解像度)] 設定では、事前に設定された DPI 値を選択できるドロップダウン フィールドが表示されますが、[Use Custom DPI (カスタム DPI を使用)] 設定をオンにすると、整数フィールドが表示されます。
Unreal Engine (UE) では、詳細ビューでカスタム編集条件を処理するための複数のパスがあります。このドキュメントでは、スレート C++ コードでの UPROPERTY の実装とカスタム編集条件の両方に関するリファレンスを提供します。
必須条件
このページでは、「[Details (詳細)] パネルのカスタマイズのクイックスタート」チュートリアルの例をベースとして使用しています。また、以下を参照しています。
- 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;
//CustomInt は bRestrictEdit が true でない場合に限り編集可能です。
UPROPERTY(EditAnywhere, meta = (DisplayName = "Custom Integer", EditCondition = "!bRestrictEdit"))
uint32 CustomInt;
//CustomFloat は CustomInt が 10 以上 20 以下かつ bRestrictEdit が false の場合に限り編集可能です。
UPROPERTY(EditAnywhere, meta=(DisplayName = "Custom Float", EditCondition = "CustomInt > 10 && CustomInt < 20 && !bRestrictEdit"))
Float CustomFloat;
また、== 演算子を使用して、特定の値に合致しているかどうかを確認することもできます。これは、編集条件として列挙型を使用する場合に役立ちます。
CustomActor.h
UPROPERTY(EditAnywhere)
ECustomIntEditMode EditMode;
//CustomInt は EditMode が AllowEdit の場合に限り編集可能です。
UPROPERTY(EditAnywhere, meta = (DisplayName = "Custom Integer", EditCondition = "EditMode==ECustomIntEditMode::AllowEdt"))
uint32 CustomInt;
UPROPERTY の編集条件における関数
現時点では、UPROPERTY の編集条件で関数の使用はサポートされていません。編集条件の基礎として関数またはデリゲートを使用する必要がある場合は、以下の「[Details] パネルのカスタマイズにおけるカスタム編集条件」セクションを参照してください。
EditConditionHides
EditConditionHides メタデータ タグを使用すると、プロパティのフィールドを無効にするだけでなく、その編集条件が満たされない場合に非表示にすることができます。
このメソッドは、前述の [Font Resolution] 設定で使用されています。C++ コードでは、UUserInterfaceSettings には、実際に、フォント DPI を処理するための次の 3 つの異なる変数が含まれています。
FontDPIPreset というEFontDPI` 列挙型。ドロップダウンのプリセットを表します。CustomFontDPIというuint32。編集可能な整数フィールドを表します。bUseCustomFontDPIというブール値。上記の両方の変数の EditCondition で使用されます。
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 は、CustomFontDPI 値を直接使用するか、FontDPIPreset を整数値に変換するかを選択するために、フォント DPI の計算で bUseCustomFontDPI を使用します。
CustomFontDPI プロパティの EditCondition は「bUseCustomFontDPI」を直接使用します。つまり、CustomFontDPI を表示して、使用するには、bUseCustomFontDPI が true である必要があります。
一方、FontDPIPreset プロパティの EditCondition は "!bUseCustomFontDPI" です。! 演算子は、FontDPIPreset を表示して使用するためには、bUseCustomFontDPI が false である必要があることを示します。
InlineEditConditionToggle
UPROPERTY メタデータ タグ InlineEditConditionToggle は、プロパティのフィールドの隣に、そのフィールドの有効/無効を切り替えるチェックボックスを提供します。これは、レンダリングのポストプロセス フィールドと同じように機能します。
//CustomInt には、有効/無効を切り替えるトグル フィールドがあり、その横に直接表示されます。
UPROPERTY(EditAnywhere, meta = (DisplayName = "Custom Integer", InlineEditConditionToggle))
uint32 CustomInt;
これは EditCondition メタデータ タグを使用しません。InlineEditConditionToggle が、独自のトグル フィールドを提供し、追跡します。
[Details] パネルのカスタマイズにおけるカスタム編集条件
[Details] パネルのカスタマイズを使用して、より複雑な編集条件、または関数を活用した編集条件を作成することができます。以下の例では、これをプロパティ フィールドおよびスレート ウィジェットの両方で示しています。
プロパティ フィールドのカスタム編集条件
プロパティ フィールド用のカスタム編集条件を作成するには、次の手順を実行します。
-
[Details] パネルをリフレッシュできるデリゲートを、リフレッシュをトリガーしたい任意のプロパティで登録します。詳細については、「[Details (詳細)] パネルをリフレッシュする」を参照してください。
-
必要に応じて、プロパティの値を取得するために
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)); }
また、プロパティの表示/非表示を切り替えるロジック、[Details] パネルの一部をビルドする動作、またはその両方をカプセル化する他の関数を記述することもできます。[Details] パネルの一部をビルドする関数のパラメータとして IDetailLayoutBuilder の参照を指定します。プロパティ ハンドルの参照またはプロパティの値のいずれかを、それらを考慮したい関数のパラメータとして指定します。
以下は、TSoftPtr<UStaticMesh> プロパティの編集条件としてブールを使用する CustomizeDetails 関数と、[Details] パネルをリフレッシュするデリゲートの完全な例です。
CustomClassDetailsCustomization.cpp
void FCustomClassDetailsCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
{
//Custom Settings カテゴリを追加します。
IDetailCategoryBuilder& CustomCategory = DetailBuilder.EditCategory(FName("Custom Settings"));
//Custom Settings カテゴリに CustomBool を追加します。
CustomCategory.AddProperty(GET_MEMBER_NAME_CHECKED(ACustomActor, CustomBool));
//CustomBool のプロパティ ハンドルを取得します。
TSharedRef<IPropertyHandle> boolPropertyHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(ACustomActor, CustomBool));
//値変更のためのデリゲートを設定します。[Details] パネルの強制リフレッシュをトリガーしたい変数のプロパティ ハンドルにこれを追加します。
const FSimpleDelegate OnValueChanged = FSimpleDelegate::CreateLambda([&DetailBuilder](){
DetailBuilder.ForceRefreshDetails();
});
//CustomBool のプロパティ ハンドルに Property Value Changed デリゲートを追加します。
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));
}
}
スレート ウィジェットのカスタム編集条件
[Details] パネルのカスタマイズで、より複雑なカスタム スレート ウィジェットの編集条件を作成する必要がある場合があります。例として、ユーザーが [Document Link (ドキュメント リンク)] フィールドに入力するまで、[Documentation Actor (ドキュメント アクタ)] の [Open Help URL (ヘルプ URL を開く)] ボタンは無効になります。
DocumentationActorDetails.cpp は、SButton を使用したカスタム行に [Open Help URL] ボタンを追加します。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 スレート パラメータの割り当ての一部として自動的に追加されるため、この実装で [Details] パネルをリフレッシュするために追加でプログラミングする必要ありません。