vault backup: 2024-10-12 17:19:45
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
# MaxPropertyDepth
|
||||
|
||||
- **功能描述:** 指定对象或结构在细节面板里展开的层数。
|
||||
- **使用位置:** UPROPERTY
|
||||
- **引擎模块:** DetailsPanel
|
||||
- **元数据类型:** int32
|
||||
- **限制类型:** 对象或结构属性
|
||||
- **常用程度:** ★
|
||||
|
||||
指定对象或结构在细节面板里展开的层数。
|
||||
|
||||
- 默认是没有限制的,可以一直递归展开到最深层次字段。
|
||||
- 如果对象的子对象再有子对象,这样递归很多层级,可能我们会想要限制不想展开太深,因此我们可以指定一个层级限制。
|
||||
- 取值-1表示没有限制,0表示完全不展开,>0表示限制的层数。
|
||||
- 源码里没有找到例子,但却是可以工作的。
|
||||
|
||||
## 测试代码:
|
||||
|
||||
```cpp
|
||||
USTRUCT(BlueprintType)
|
||||
struct INSIDER_API FMyStructDepth1
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
int32 MyInt1 = 123;
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
FString MyString1;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct INSIDER_API FMyStructDepth2
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
FMyStructDepth1 MyStruct1;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct INSIDER_API FMyStructDepth3
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
FMyStructDepth2 MyStruct2;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct INSIDER_API FMyStructDepth4
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
FMyStructDepth3 MyStruct3;
|
||||
};
|
||||
|
||||
UCLASS(BlueprintType)
|
||||
class INSIDER_API UMyProperty_MaxPropertyDepth :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FMyStructDepth4 MyStruct;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite,meta=(MaxPropertyDepth=2))
|
||||
FMyStructDepth4 MyStruct_Depth;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## 测试效果:
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
在每个FPropertyNode构建子节点的时候,检查一下当前的MaxChildDepthAllowed ,超过了就不继续往下构建。
|
||||
|
||||
```cpp
|
||||
/** Safety Value representing Depth in the property tree used to stop diabolical topology cases
|
||||
* -1 = No limit on children
|
||||
* 0 = No more children are allowed. Do not process child nodes
|
||||
* >0 = A limit has been set by the property and will tick down for successive children
|
||||
*/
|
||||
int32 MaxChildDepthAllowed;
|
||||
|
||||
void FPropertyNode::InitNode(const FPropertyNodeInitParams& InitParams)
|
||||
{
|
||||
|
||||
//Get the property max child depth
|
||||
static const FName Name_MaxPropertyDepth("MaxPropertyDepth");
|
||||
if (Property->HasMetaData(Name_MaxPropertyDepth))
|
||||
{
|
||||
int32 NewMaxChildDepthAllowed = Property->GetIntMetaData(Name_MaxPropertyDepth);
|
||||
//Ensure new depth is valid. Otherwise just let the parent specified value stand
|
||||
if (NewMaxChildDepthAllowed > 0)
|
||||
{
|
||||
//if there is already a limit on the depth allowed, take the minimum of the allowable depths
|
||||
if (MaxChildDepthAllowed >= 0)
|
||||
{
|
||||
MaxChildDepthAllowed = FMath::Min(MaxChildDepthAllowed, NewMaxChildDepthAllowed);
|
||||
}
|
||||
else
|
||||
{
|
||||
//no current limit, go ahead and take the new limit
|
||||
MaxChildDepthAllowed = NewMaxChildDepthAllowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FPropertyNode::RebuildChildren()
|
||||
{
|
||||
if (MaxChildDepthAllowed != 0)
|
||||
{
|
||||
//the case where we don't want init child nodes is when an Item has children that we don't want to display
|
||||
//the other option would be to make each node "Read only" under that item.
|
||||
//The example is a material assigned to a static mesh.
|
||||
if (HasNodeFlags(EPropertyNodeFlags::CanBeExpanded) && (ChildNodes.Num() == 0))
|
||||
{
|
||||
InitChildNodes();
|
||||
if (ExpandedPropertyItemSet.Size() > 0)
|
||||
{
|
||||
FPropertyNodeUtils::SetExpandedItems(ThisAsSharedRef, ExpandedPropertyItemSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
Reference in New Issue
Block a user