vault backup: 2024-10-12 17:19:45

This commit is contained in:
2024-10-12 17:19:46 +08:00
parent ff94ddca61
commit 244c0c52f6
960 changed files with 31348 additions and 10 deletions

View File

@@ -0,0 +1,9 @@
# DataflowFlesh
- **功能描述:** ScriptStruct /Script/DataflowNodes.FloatOverrideDataflowNode
- **使用位置:** USTRUCT
- **引擎模块:** Struct
- **元数据类型:** bool
- **常用程度:** 0
没有在源码里找到应用的例子

View File

@@ -0,0 +1,100 @@
# HasNativeBreak
- **功能描述:** 为该结构指定一个C++内的UFunction函数作为Break节点的实现
- **使用位置:** USTRUCT
- **引擎模块:** Struct
- **元数据类型:** string="abc"
- **关联项:** [HasNativeMake](../HasNativeMake.md)
- **常用程度:** ★★★★★
为该结构指定一个C++内的UFunction函数作为Break节点的实现
指定一个static *UFunction函数的完整路径值一般是”/*Script/*Module.Class.Function”*
这个函数一般是BlueprintThreadSafe因为这种纯Make和Break函数一般不带副作用因此可以随便的多线程调用。
## 测试代码:
```cpp
//(BlueprintType = true, HasNativeBreak = /Script/Insider.MyHasNativeStructHelperLibrary.BreakMyHasNativeStruct, HasNativeMake = /Script/Insider.MyHasNativeStructHelperLibrary.MakeMyHasNativeStruct, ModuleRelativePath = Struct/MyStruct_NativeMakeBreak.h)
USTRUCT(BlueprintType, meta = (HasNativeBreak = "/Script/Insider.MyHasNativeStructHelperLibrary.BreakMyHasNativeStruct", HasNativeMake = "/Script/Insider.MyHasNativeStructHelperLibrary.MakeMyHasNativeStruct"))
struct INSIDER_API FMyStruct_HasNative
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite, EditAnywhere)
float MyReadWrite;
UPROPERTY(BlueprintReadOnly, EditAnywhere)
float MyReadOnly;
UPROPERTY(EditAnywhere)
float MyNotBlueprint;
};
USTRUCT(BlueprintType)
struct INSIDER_API FMyStruct_HasDefaultMakeBreak
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite, EditAnywhere)
float MyReadWrite;
UPROPERTY(BlueprintReadOnly, EditAnywhere)
float MyReadOnly;
UPROPERTY(EditAnywhere)
float MyNotBlueprint;
};
UCLASS()
class UMyHasNativeStructHelperLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintPure, meta = (BlueprintThreadSafe))
static void BreakMyHasNativeStruct(const FMyStruct_HasNative& myStruct, float& outValue)
{
outValue = myStruct.MyReadWrite + myStruct.MyReadOnly + myStruct.MyNotBlueprint;
}
UFUNCTION(BlueprintPure, meta = (BlueprintThreadSafe))
static FMyStruct_HasNative MakeMyHasNativeStruct(float value)
{
FMyStruct_HasNative result;
result.MyReadWrite = value;
result.MyReadOnly = value;
result.MyNotBlueprint = value;
return result;
}
};
```
## 蓝图节点:
![Untitled](Untitled.png)
## 原理是:
通过Meta里配置的值去找UFunction函数因此我们配置的时候需要提供的是能找到UFunction的完整路径值。这个函数的签名会自动的被反射提取信息到UK2Node_CallFunction节点上从而构造出不同样式的Make和Break蓝图节点。
```cpp
E:\P4V\Engine\Source\Editor\BlueprintGraph\Private\EdGraphSchema_K2.cpp
const FString& MetaData = StructType->GetMetaData(FBlueprintMetadata::MD_NativeMakeFunction);
const UFunction* Function = FindObject<UFunction>(nullptr, *MetaData, true);
UK2Node_CallFunction* CallFunctionNode;
if (Params.bTransient || Params.CompilerContext)
{
CallFunctionNode = (Params.bTransient ? NewObject<UK2Node_CallFunction>(Graph) : Params.CompilerContext->SpawnIntermediateNode<UK2Node_CallFunction>(GraphNode, Params.SourceGraph));
CallFunctionNode->SetFromFunction(Function);
CallFunctionNode->AllocateDefaultPins();
}
else
{
FGraphNodeCreator<UK2Node_CallFunction> MakeStructCreator(*Graph);
CallFunctionNode = MakeStructCreator.CreateNode(false);
CallFunctionNode->SetFromFunction(Function);
MakeStructCreator.Finalize();
}
SplitPinNode = CallFunctionNode;
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

@@ -0,0 +1,7 @@
# HasNativeMake
- **功能描述:** 为该结构指定一个C++内的UFunction函数作为Mreak节点的实现
- **使用位置:** USTRUCT
- **元数据类型:** string="abc"
- **关联项:** [HasNativeBreak](HasNativeBreak/HasNativeBreak.md)
- **常用程度:** ★★★★★

View File

@@ -0,0 +1,69 @@
# IgnoreForMemberInitializationTest
- **功能描述:** 使得该属性忽略结构的未初始验证。
- **使用位置:** UPROPERTY
- **引擎模块:** Struct
- **元数据类型:** bool
- **限制类型:** C++结构下的属性
- **常用程度:** ★★
使得该属性忽略结构的未初始验证。
- 所谓未初始化指的是C++结构里的变量没有在构造函数里初始化,也没有直接写上初始值
- 结构未初始验证指的是引擎提供的验证工具可采用控制台命令“CoreUObject.AttemptToFindUninitializedScriptStructMembers”调用。然后会输出引擎内所有未初始化的变量信息。
- UE里的USTRUCT只是一个纯C++结构不像用UCLASS定义的类都是一个UObject后者的UPROPERTY属性会自动的都初始化为0而结构里的UPROPERTY并不会自动的初始化因此就需要我们手动的初始化。
- 从实践来说如果开发者清楚知道某变量未初始化不会影响逻辑那即使未初始化也并没有关系。但现实是往往大家绝大多数情况下只是单纯的犯懒或者遗忘给属性初始化。因此还是建议大家尽量给结构里的所有属性都初始化值。但一些特殊情况下某些属性确实不适合初始化比如源码例子里一些FGuid变量只在真正用到的时候才手动赋值在这之前初始化什么值其实都意义不大。在这种情况下就可以用IgnoreForMemberInitializationTest来使该属性忽略这个验证避免输出报错信息。
## 测试代码:
```cpp
USTRUCT(BlueprintType)
struct INSIDER_API FMyStruct_InitTest
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int32 MyProperty;
UPROPERTY(EditAnywhere, BlueprintReadWrite,meta=(IgnoreForMemberInitializationTest))
int32 MyProperty_IgnoreTest;
};
```
## 测试结果:
可见MyProperty因为没有IgnoreForMemberInitializationTest就报错了。
```cpp
在控制台调用CoreUObject.AttemptToFindUninitializedScriptStructMembers后
LogClass: Error: IntProperty FMyStruct_InitTest::MyProperty is not initialized properly. Module:Insider File:Property/Struct/MyProperty_Struct.h
```
## 原理:
这个命令行调用AttemptToFindUninitializedScriptStructMembers继而继续调用FindUninitializedScriptStructMembers来查找出UScriptStruct中的未初始化变量。具体的找出方式可以在该函数中细看。
```cpp
static void FindUninitializedScriptStructMembers(UScriptStruct* ScriptStruct, EScriptStructTestCtorSyntax ConstructorSyntax, TSet<const FProperty*>& OutUninitializedProperties)
{
for (const FProperty* Property : TFieldRange<FProperty>(ScriptStruct, EFieldIteratorFlags::ExcludeSuper))
{
#if WITH_EDITORONLY_DATA
static const FName NAME_IgnoreForMemberInitializationTest(TEXT("IgnoreForMemberInitializationTest"));
if (Property->HasMetaData(NAME_IgnoreForMemberInitializationTest))
{
continue;
}
#endif // WITH_EDITORONLY_DATA
}
//由这个调用
FStructUtils::AttemptToFindUninitializedScriptStructMembers();
// 命令行调用
CoreUObject.AttemptToFindUninitializedScriptStructMembers
```

View File

@@ -0,0 +1,71 @@
# MakeStructureDefaultValue
- **功能描述:** 存储BP中自定义结构里的属性的默认值。
- **使用位置:** UPROPERTY
- **引擎模块:** Struct
- **元数据类型:** bool
- **限制类型:** BP里的用户自定义Struct
- **常用程度:** ★
存储BP中自定义结构里的属性的默认值。
- 在C++中我们写的USTRUCT的结构里的属性默认值并不需要存储在元数据中因为在创建该结构实例的时候就自然会调用该结构的构造函数从而正确初始化值。
- 而在蓝图中的用户自定义结构并没有构造函数之类的机制。因此我们需要一个专门的Tab来填写属性的默认值。这些默认值就会存储在属性的元数据中。
-
## 测试代码:
在蓝图中定义一个结构BP_StructDefaultTest并填上默认值。
![Untitled](Untitled.png)
## 测试结果:
用测试命令行打印出其相关的信息可以见到MyInt和MyString的真正属性名以及MakeStructureDefaultValue 的值。
```cpp
[struct BP_StructDefaultTest UserDefinedStruct->ScriptStruct->Struct->Field->Object /Game/Struct/BP_StructDefaultTest.BP_StructDefaultTest]
(BlueprintType = true, Tooltip = )
ObjectFlags: RF_Public | RF_Standalone | RF_Transactional | RF_WasLoaded | RF_LoadCompleted
Outer: Package /Game/Struct/BP_StructDefaultTest
StructFlags: STRUCT_NoFlags
Size: 24
{
(DisplayName = MyInt, Tooltip = , MakeStructureDefaultValue = 789)
0-[4] int32 MyInt_3_CC664A574A072369083883B38EA2F129;
PropertyFlags: CPF_Edit | CPF_BlueprintVisible | CPF_ZeroConstructor | CPF_IsPlainOldData | CPF_NoDestructor | CPF_HasGetValueTypeHash
ObjectFlags: RF_Public | RF_LoadCompleted
Outer: UserDefinedStruct /Game/Struct/BP_StructDefaultTest.BP_StructDefaultTest
Path: IntProperty /Game/Struct/BP_StructDefaultTest.BP_StructDefaultTest:MyInt_3_CC664A574A072369083883B38EA2F129
(DisplayName = MyString, Tooltip = , MakeStructureDefaultValue = Hello)
8-[16] FString MyString_6_D8FAF5D6454C781C2D5175ACF266C394;
PropertyFlags: CPF_Edit | CPF_BlueprintVisible | CPF_ZeroConstructor | CPF_HasGetValueTypeHash
ObjectFlags: RF_Public | RF_LoadCompleted
Outer: UserDefinedStruct /Game/Struct/BP_StructDefaultTest.BP_StructDefaultTest
Path: StrProperty /Game/Struct/BP_StructDefaultTest.BP_StructDefaultTest:MyString_6_D8FAF5D6454C781C2D5175ACF266C394
};
```
## 原理:
在BP中结构创建变量保存的时候如果发现默认值不为空则设置到MakeStructureDefaultValue中去。之后再MakeStruct的时候就可以用上了。
```cpp
void UK2Node_MakeStruct::FMakeStructPinManager::CustomizePinData(UEdGraphPin* Pin, FName SourcePropertyName, int32 ArrayIndex, FProperty* Property) const
{
const FString& MetadataDefaultValue = Property->GetMetaData(TEXT("MakeStructureDefaultValue"));
if (!MetadataDefaultValue.IsEmpty())
{
Schema->SetPinAutogeneratedDefaultValue(Pin, MetadataDefaultValue);
return;
}
}
static void FUserDefinedStructureCompilerInner::CreateVariables(UUserDefinedStruct* Struct, const class UEdGraphSchema_K2* Schema, FCompilerResultsLog& MessageLog)
{
if (!VarDesc.DefaultValue.IsEmpty())
{
VarProperty->SetMetaData(TEXT("MakeStructureDefaultValue"), *VarDesc.DefaultValue);
}
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB