100 lines
4.6 KiB
Markdown
100 lines
4.6 KiB
Markdown
|
# NonPIEDuplicateTransient
|
|||
|
|
|||
|
- **功能描述:** 在对象复制的时候,且在不是PIE的场合,忽略该属性。
|
|||
|
|
|||
|
- **元数据类型:** bool
|
|||
|
- **引擎模块:** Serialization
|
|||
|
- **作用机制:** 在PropertyFlags中加入[CPF_NonPIEDuplicateTransient](../../../../Flags/EPropertyFlags/CPF_NonPIEDuplicateTransient.md)
|
|||
|
- **常用程度:** ★
|
|||
|
|
|||
|
在对象复制的时候,且在不是PIE的场合,忽略该属性。
|
|||
|
|
|||
|
- DuplicateTransient和NonPIEDuplicateTransient的区别是,前者在任何情况的对象复制时都忽略该属性,而后者在PIE的时候(也是在发生对象复制过程)依然会复制该属性,其他情况下的复制和前者行为一致。
|
|||
|
- PIE的时候本质就是把当前的编辑World里Actor复制一份到PIE的世界里,会触发Actor的复制。
|
|||
|
|
|||
|
## 示例代码:
|
|||
|
|
|||
|
准备了一份DataAsset和Actor来分别验证复制行为的不同。
|
|||
|
|
|||
|
```cpp
|
|||
|
UCLASS(Blueprintable, BlueprintType)
|
|||
|
class INSIDER_API UMyProperty_Serialization :public UDataAsset
|
|||
|
{
|
|||
|
public:
|
|||
|
GENERATED_BODY()
|
|||
|
public:
|
|||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
|||
|
int32 MyInt_Default = 123;
|
|||
|
//PropertyFlags: CPF_Edit | CPF_BlueprintVisible | CPF_ZeroConstructor | CPF_Transient | CPF_IsPlainOldData | CPF_NoDestructor | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPublic
|
|||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Transient)
|
|||
|
int32 MyInt_Transient = 123;
|
|||
|
//PropertyFlags: CPF_Edit | CPF_BlueprintVisible | CPF_ZeroConstructor | CPF_DuplicateTransient | CPF_IsPlainOldData | CPF_NoDestructor | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPublic
|
|||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, DuplicateTransient)
|
|||
|
int32 MyInt_DuplicateTransient = 123;
|
|||
|
//PropertyFlags: CPF_Edit | CPF_BlueprintVisible | CPF_ZeroConstructor | CPF_IsPlainOldData | CPF_NoDestructor | CPF_NonPIEDuplicateTransient | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPublic
|
|||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, NonPIEDuplicateTransient)
|
|||
|
int32 MyInt_NonPIEDuplicateTransient = 123;
|
|||
|
};
|
|||
|
|
|||
|
UCLASS(Blueprintable, BlueprintType)
|
|||
|
class INSIDER_API AMyProperty_Serialization_TestActor :public AActor
|
|||
|
{
|
|||
|
public:
|
|||
|
GENERATED_BODY()
|
|||
|
protected:
|
|||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
|||
|
int32 MyInt_Default = 123;
|
|||
|
//PropertyFlags: CPF_Edit | CPF_BlueprintVisible | CPF_ZeroConstructor | CPF_Transient | CPF_IsPlainOldData | CPF_NoDestructor | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPublic
|
|||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Transient)
|
|||
|
int32 MyInt_Transient = 123;
|
|||
|
//PropertyFlags: CPF_Edit | CPF_BlueprintVisible | CPF_ZeroConstructor | CPF_DuplicateTransient | CPF_IsPlainOldData | CPF_NoDestructor | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPublic
|
|||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, DuplicateTransient)
|
|||
|
int32 MyInt_DuplicateTransient = 123;
|
|||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, NonPIEDuplicateTransient)
|
|||
|
int32 MyInt_NonPIEDuplicateTransient = 123;
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
## 示例效果:
|
|||
|
|
|||
|
在对资产进行Duplidate的时候,发生DuplicateAsset然后DuplicateObject,这个时候PortFlags=PPF_Duplicate,然后会触发ShouldSerializeValue进行判断。这个时候会跳过该属性。
|
|||
|
|
|||
|
可以看到NonPIEDuplicateTransient并不会被复制。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
在点击PIE的时候,可以看到NonPIEDuplicateTransient这个时候却是会复制值过去了。这是因为这个时候PortFlags=PPF_DuplicateForPIE&PPF_Duplicate
|
|||
|
|
|||
|

|
|||
|
|
|||
|
结论是用于一些Cache数据,在复制的时候并不需要序列化复制,这样可以阻止两个不同的Actor采用同一份计算后的临时数据。但是又可以在PIE的时候,让Actor各自采用自己的一份数据,因为PIE的时候,本质就是把当前的编辑World里Actor复制一份到PIE的世界里,会触发Actor的复制。
|
|||
|
|
|||
|
## 原理:
|
|||
|
|
|||
|
在文本导出的的时候,在不是PIE里的复制的时候,不序列化该属性。
|
|||
|
|
|||
|
```cpp
|
|||
|
bool FProperty::ShouldPort( uint32 PortFlags/*=0*/ ) const
|
|||
|
{
|
|||
|
// if we're not copying for PIE and NonPIETransient is set, don't export
|
|||
|
if (!(PortFlags & PPF_DuplicateForPIE) && HasAnyPropertyFlags(CPF_NonPIEDuplicateTransient))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
在二进制序列化的时候:
|
|||
|
|
|||
|
只有在PPF_Duplicate生效的时候,(DuplicateObject?或者资产复制),才会跳过该属性。但是在PIE的时候,又要继续序列化。
|
|||
|
|
|||
|
```cpp
|
|||
|
bool FProperty::ShouldSerializeValue(FArchive& Ar) const
|
|||
|
{
|
|||
|
// Skip properties marked NonPIEDuplicateTransient when duplicating, but not when we're duplicating for PIE
|
|||
|
if ((PropertyFlags & CPF_NonPIEDuplicateTransient) && !(Ar.GetPortFlags() & PPF_DuplicateForPIE) && (Ar.GetPortFlags() & PPF_Duplicate))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
```
|