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,56 @@
# Abstract
- **功能描述:** 标识该FRigUnit为抽象类不用实现Execute。
- **使用位置:** USTRUCT
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **限制类型:** FRigUnit类型上
- **常用程度:** ★★
标识该FRigUnit为抽象类不用实现Execute常常用作别的FRigUnit类的基类使用。
但如果还是实现了Execute其实也还是可以在蓝图中调用的。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName = "MyRigAbstract",Abstract))
struct INSIDER_API FRigUnit_MyRigAbstract: public FRigUnit
{
GENERATED_BODY()
public:
UPROPERTY(meta = (Input))
float MyFloat_Input = 123.f;
UPROPERTY(meta = (Output))
float MyFloat_Output = 123.f;
};
```
## 测试效果:
![Untitled](Untitled.png)
## 原理:
在一些内部处理的时候,当然会略过这种抽象基类。
```cpp
void FRigVMBlueprintUtils::ForAllRigVMStructs(TFunction<void(UScriptStruct*)> InFunction)
{
// Run over all unit types
for(TObjectIterator<UStruct> StructIt; StructIt; ++StructIt)
{
if (*StructIt)
{
if(StructIt->IsChildOf(FRigVMStruct::StaticStruct()) && !StructIt->HasMetaData(FRigVMStruct::AbstractMetaName))
{
if (UScriptStruct* ScriptStruct = Cast<UScriptStruct>(*StructIt))
{
InFunction(ScriptStruct);
}
}
}
}
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,74 @@
# Aggregate
- **功能描述:** 指定FRigUnit里的属性引脚为可扩展连续二元运算符的运算数。
- **使用位置:** UPROPERTY
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **限制类型:** FRigUnit下的属性
- **常用程度:** ★★★
指定FRigUnit里的属性引脚为可扩展连续二元运算符的运算数。
记得在Input和Output上都加上Aggregate。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName = "MyRigAggregate"))
struct INSIDER_API FRigUnit_MyRigAggregate : public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY(meta = (Input,Aggregate))
float A = 0.f;
UPROPERTY(meta = (Input,Aggregate))
float B= 0.f;
UPROPERTY(meta = (Output,Aggregate))
float Result = 0.f;
};
```
## 测试效果:
可见加了Aggregate之后在蓝图节点上就可以继续动态AddPin。在左侧的Graph上也会创建中间MyRigAggregate节点。点开后可以看见其实就是继续组装原始的二元运算来达成继续AddPin的效果。
![Untitled](Untitled.png)
## 原理:
识别该Meta然后然后把引脚加到AggregateInputs和AggregateOutputs里。
```cpp
TArray<URigVMPin*> URigVMUnitNode::GetAggregateInputs() const
{
TArray<URigVMPin*> AggregateInputs;
#if UE_RIGVM_AGGREGATE_NODES_ENABLED
if (const UScriptStruct* Struct = GetScriptStruct())
{
for (URigVMPin* Pin : GetPins())
{
if (Pin->GetDirection() == ERigVMPinDirection::Input)
{
if (const FProperty* Property = Struct->FindPropertyByName(Pin->GetFName()))
{
if (Property->HasMetaData(FRigVMStruct::AggregateMetaName))
{
AggregateInputs.Add(Pin);
}
}
}
}
}
else
{
return Super::GetAggregateInputs();
}
#endif
return AggregateInputs;
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

View File

@@ -0,0 +1,19 @@
# Constant
- **功能描述:** 标识一个属性成为一个常量的引脚。
- **使用位置:** UPROPERTY, USTRUCT
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **关联项:** [Input](Input/Input.md)
- **常用程度:** ★★★
放在UPROPERTY上的时候和Visible一样标识一个属性成为一个常量的引脚。
放在USTRUCT上的时候发现用在IsDefinedAsConstant这种函数上但是F5没有发现调用的地方。
```cpp
USTRUCT(meta = (DisplayName = "Rotation Order", Category = "Math|Quaternion", Constant))
struct RIGVM_API FRigVMFunction_MathQuaternionRotationOrder : public FRigVMFunction_MathBase
{
}
```

View File

@@ -0,0 +1,60 @@
# CustomWidget
- **功能描述:** 指定该FRigUnit里的属性要用自定义的控件来编辑。
- **使用位置:** UPROPERTY
- **引擎模块:** RigVMStruct
- **元数据类型:** string="abc"
- **限制类型:** FRigUnit中的属性
- **常用程度:** ★★
指定该FRigUnit里的属性要用自定义的控件来编辑。
CustomWidget的值是在一些选项中选择的这些自定义控件是已经在引擎中实现的。
可用的列表为BoneNameControlNameSpaceName/NullNameCurveNameElementNameConnectorNameDrawingNameShapeNameAnimationChannelNameMetadataNameMetadataTagName。
测试代码里就只用BoneName作为测试展示
```cpp
USTRUCT(meta = (DisplayName = "MyRigCustomWidget"))
struct INSIDER_API FRigUnit_MyRigCustomWidget : public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY(meta = (Input))
FString MyString;
UPROPERTY(meta = (Input, CustomWidget = "BoneName"))
FString MyString_Custom;
UPROPERTY(meta = (Output))
float MyFloat_Output = 123.f;
};
```
## 测试效果:
可见MyString_Custom的Pin类型变成可选BoneName的列表。
![Untitled](Untitled.png)
## 原理:
```cpp
TSharedPtr<SGraphPin> FControlRigGraphPanelPinFactory::CreatePin_Internal(UEdGraphPin* InPin) const
{
if (CustomWidgetName == TEXT("BoneName"))
{
return SNew(SRigVMGraphPinNameList, InPin)
.ModelPin(ModelPin)
.OnGetNameFromSelection_UObject(RigGraph, &UControlRigGraph::GetSelectedElementsNameList)
.OnGetNameListContent_UObject(RigGraph, &UControlRigGraph::GetBoneNameList)
.OnGetSelectedClicked_UObject(RigGraph, &UControlRigGraph::HandleGetSelectedClicked)
.OnBrowseClicked_UObject(RigGraph, &UControlRigGraph::HandleBrowseClicked);
}
//等等其他
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -0,0 +1,59 @@
# Deprecated
- **功能描述:** 标识该FRigUnit为弃用状态不在蓝图右键菜单中显示。
- **使用位置:** USTRUCT
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **限制类型:** FRigUnit类型上
- **常用程度:** ★★
标识该FRigUnit为弃用状态不在蓝图右键菜单中显示。
但如果之前已经在蓝图中使用了,则还是可以继续使用。
注意这个时候要相应的实现GetUpgradeInfo(),否则会报错。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName = "MyRigDeprecated",Deprecated))
struct INSIDER_API FRigUnit_MyRigDeprecated : public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
RIGVM_METHOD()
virtual FRigVMStructUpgradeInfo GetUpgradeInfo() const override;
public:
UPROPERTY(meta = (Input))
float MyFloat_Input = 123.f;
UPROPERTY(meta = (Output))
float MyFloat_Output = 123.f;
};
```
## 测试效果:
![Untitled](Untitled.png)
## 原理:
在构建菜单项的时候略过Deprecated的节点。
```cpp
void FRigVMEditorModule::GetTypeActions(URigVMBlueprint* RigVMBlueprint, FBlueprintActionDatabaseRegistrar& ActionRegistrar)
{
// Add all rig units
for(const FRigVMFunction& Function : Registry.GetFunctions())
{
// skip deprecated units
if(Function.Struct->HasMetaData(FRigVMStruct::DeprecatedMetaName))
{
continue;
}
}
}
```

View File

@@ -0,0 +1,58 @@
# DetailsOnly
- **功能描述:** 指定FRigUnit下的该属性只在细节面板中显示。
- **使用位置:** UPROPERTY
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **限制类型:** FRigUnit下的属性
- **关联项:** [Input](../Input/Input.md)
- **常用程度:** ★★★
指定FRigUnit下的该属性只在细节面板中显示。
## 测试代码:
```cpp
UPROPERTY(meta = (Input, DetailsOnly))
float MyFloat_DetailsOnly = 456.f;
```
## 测试效果:
![Untitled](Untitled.png)
## 原理:
根据DetailsOnly判断返回是否ShowInDetailsPanelOnly。
```cpp
bool URigVMPin::ShowInDetailsPanelOnly() const
{
#if WITH_EDITOR
if (GetParentPin() == nullptr)
{
if (URigVMUnitNode* UnitNode = Cast<URigVMUnitNode>(GetNode()))
{
if (UScriptStruct* ScriptStruct = UnitNode->GetScriptStruct())
{
if (FProperty* Property = ScriptStruct->FindPropertyByName(GetFName()))
{
if (Property->HasMetaData(FRigVMStruct::DetailsOnlyMetaName))
{
return true;
}
}
}
}
else if(const URigVMTemplateNode* TemplateNode = Cast<URigVMTemplateNode>(GetNode()))
{
if(const FRigVMTemplate* Template = TemplateNode->GetTemplate())
{
return !Template->GetArgumentMetaData(GetFName(), FRigVMStruct::DetailsOnlyMetaName).IsEmpty();
}
}
}
#endif
return false;
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1,46 @@
# ExpandByDefault
- **功能描述:** 把FRigUnit里的属性引脚默认展开。
- **使用位置:** UPROPERTY
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **常用程度:** ★★★
把FRigUnit里的属性引脚默认展开。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName = "MyRig"))
struct INSIDER_API FRigUnit_MyRig : public FRigUnit
{
UPROPERTY(meta = (Input))
FMyCommonStruct MyStruct_Normal;
UPROPERTY(meta = (Input, ExpandByDefault))
FMyCommonStruct MyStruct_ExpandByDefault;
UPROPERTY(meta = (Output))
float MyFloat_Output = 123.f;
```
## 测试效果:
可见MyStruct_ExpandByDefault默认状态下就把该结构展开。
![Untitled](Untitled.png)
## 原理:
识别该Meta然后设定该引脚的bIsExpanded状态。
```cpp
FRigVMPinInfo::FRigVMPinInfo(FProperty* InProperty, ERigVMPinDirection InDirection, int32 InParentIndex, const uint8* InDefaultValueMemory)
{
if (InProperty->HasMetaData(FRigVMStruct::ExpandPinByDefaultMetaName))
{
bIsExpanded = true;
}
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,9 @@
# Hidden
- **功能描述:** 指定FRigUnit下的该属性隐藏
- **使用位置:** UPROPERTY
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **限制类型:** FRigUnit中属性
- **关联项:** [Input](Input/Input.md)
- **常用程度:** ★★★

View File

@@ -0,0 +1,63 @@
# Icon
- **功能描述:** 设定FRigUnit蓝图节点的图标。
- **使用位置:** USTRUCT
- **引擎模块:** RigVMStruct
- **元数据类型:** string="abc"
- **限制类型:** FRigUnit
- **常用程度:** ★★
设定FRigUnit蓝图节点的图标。
根据源码中的注释得知Icon的格式是“StyleSetName|StyleName|SmallStyleName|StatusOverlayStyleName”最后两项是可选的可参考FSlateIcon的更多介绍。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName = "MyRigIcon",Icon="EditorStyle|GraphEditor.Macro.ForEach_16x"))
struct INSIDER_API FRigUnit_MyRigIcon: public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY(meta = (Input))
float MyFloat_Input = 123.f;
UPROPERTY(meta = (Output))
float MyFloat_Output = 123.f;
};
```
## 测试效果:
可见加了Icon之后左上角图标变成了其他不是默认的f函数目标。
![Untitled](Untitled.png)
## 原理:
```cpp
FSlateIcon URigVMEdGraphNode::GetIconAndTint(FLinearColor& OutColor) const
{
if(MetadataScriptStruct && MetadataScriptStruct->HasMetaDataHierarchical(FRigVMStruct::IconMetaName))
{
FString IconPath;
const int32 NumOfIconPathNames = 4;
FName IconPathNames[NumOfIconPathNames] = {
NAME_None, // StyleSetName
NAME_None, // StyleName
NAME_None, // SmallStyleName
NAME_None // StatusOverlayStyleName
};
// icon path format: StyleSetName|StyleName|SmallStyleName|StatusOverlayStyleName
// the last two names are optional, see FSlateIcon() for reference
MetadataScriptStruct->GetStringMetaDataHierarchical(FRigVMStruct::IconMetaName, &IconPath);
return FSlateIcon(IconPathNames[0], IconPathNames[1], IconPathNames[2], IconPathNames[3]);
}
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

View File

@@ -0,0 +1,99 @@
# Input
- **功能描述:** 指定FRigUnit下的该属性作为输入引脚。
- **使用位置:** UPROPERTY
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **限制类型:** FRigUnit中属性
- **关联项:** [Output](../Output.md), [Visible](../Visible/Visible.md), [Hidden](../Hidden.md), [DetailsOnly](../DetailsOnly/DetailsOnly.md), [Constant](../Constant.md)
- **常用程度:** ★★★★★
指定FRigUnit下的该属性作为输入引脚。
值得注意的是一个引脚如果同时加上Input和Output那它就变成IO引脚同时可作为输入和输出。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName="MyRig"))
struct INSIDER_API FRigUnit_MyRig : public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY()
float MyFloat_Normal;
UPROPERTY(meta = (Input))
float MyFloat_Input;
UPROPERTY(meta = (Output))
float MyFloat_Output;
UPROPERTY(meta = (Input, Output))
float MyFloat_IO;
UPROPERTY(meta = (Visible))
float MyFloat_Visible;
UPROPERTY(meta = (Hidden))
float MyFloat_Hidden;
};
```
## 测试效果:
在ControlRig蓝图里就可以调用MyRig节点注意观察属性在蓝图节点上的引脚表现以及在右侧细节面板的显示。
- MyFloat_Normal不标meta在两个地方都没有显示。
- MyFloat_Input作为输入引脚且在右侧细节面板也显示。
- MyFloat_Output作为输出引脚右侧细节面板不显示。
- MyFloat_IO可以同时作为输入和输出引脚右侧细节面板会显示。
- MyFloat_Visible可以作为输入引脚显示右侧细节面板会显示。但是无法连接变量意思是只能作为常量使用。
- MyFloat_Hidden如同MyFloat_Normal一样在蓝图节点和细节面板都隐藏起来只是作为自己的内部值使用。
![Untitled](Untitled.png)
## 原理:
根据属性上的Meta标记来区分引脚的方向。可以在源码里查看ERigVMPinDirection 的各个类型。
```cpp
UENUM(BlueprintType)
enum class ERigVMPinDirection : uint8
{
Input, // A const input value
Output, // A mutable output value
IO, // A mutable input and output value
Visible, // A const value that cannot be connected to
Hidden, // A mutable hidden value (used for interal state)
Invalid // The max value for this enum - used for guarding.
};
ERigVMPinDirection FRigVMStruct::GetPinDirectionFromProperty(FProperty* InProperty)
{
bool bIsInput = InProperty->HasMetaData(InputMetaName);
bool bIsOutput = InProperty->HasMetaData(OutputMetaName);
bool bIsVisible = InProperty->HasMetaData(VisibleMetaName);
if (bIsVisible)
{
return ERigVMPinDirection::Visible;
}
if (bIsInput)
{
return bIsOutput ? ERigVMPinDirection::IO : ERigVMPinDirection::Input;
}
if(bIsOutput)
{
return ERigVMPinDirection::Output;
}
return ERigVMPinDirection::Hidden;
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

View File

@@ -0,0 +1,61 @@
# Keywords
- **功能描述:** 设定FRigUnit蓝图节点在右键菜单中的关键字方便输入查找。
- **使用位置:** USTRUCT
- **引擎模块:** RigVMStruct
- **元数据类型:** strings="abc"
- **限制类型:** FRigUnit
- **常用程度:** ★★★
设定FRigUnit蓝图节点在右键菜单中的关键字方便输入查找。
同Function上的Keywords有一样的作用。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName = "MyRigKeywords",Keywords="MyKey,OtherWord"))
struct INSIDER_API FRigUnit_MyRigKeywords: public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY(meta = (Input))
float MyFloat_Input = 123.f;
UPROPERTY(meta = (Output))
float MyFloat_Output = 123.f;
};
```
## 测试效果:
在输入Keywords中的字符的时候也可以找到该节点。
![Untitled](Untitled.png)
## 原理:
```cpp
URigVMEdGraphUnitNodeSpawner* URigVMEdGraphUnitNodeSpawner::CreateFromStruct(UScriptStruct* InStruct, const FName& InMethodName, const FText& InMenuDesc, const FText& InCategory, const FText& InTooltip)
{
FString KeywordsMetadata, TemplateNameMetadata;
InStruct->GetStringMetaDataHierarchical(FRigVMStruct::KeywordsMetaName, &KeywordsMetadata);
if(!TemplateNameMetadata.IsEmpty())
{
if(KeywordsMetadata.IsEmpty())
{
KeywordsMetadata = TemplateNameMetadata;
}
else
{
KeywordsMetadata = KeywordsMetadata + TEXT(",") + TemplateNameMetadata;
}
}
MenuSignature.Keywords = FText::FromString(KeywordsMetadata);
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,57 @@
# MenuDescSuffix
- **功能描述:** 标识FRigUnit在蓝图右键菜单项的名字后缀。
- **使用位置:** USTRUCT
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **限制类型:** FRigUnit类型上
- **常用程度:** ★★★
标识FRigUnit在蓝图右键菜单项的名字后缀。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName = "MyRigSuffix", MenuDescSuffix = "(MyVector)"))
struct INSIDER_API FRigUnit_MyRigSuffix: public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY(meta = (Input))
float MyFloat_Input = 123.f;
UPROPERTY(meta = (Output))
float MyFloat_Output = 123.f;
};
```
## 测试效果:
可见出现了"(MyVector)"的后缀。
![Untitled](Untitled.png)
## 原理:
得到该数据然后添加到DisplayName后面。
```cpp
FString CategoryMetadata, DisplayNameMetadata, MenuDescSuffixMetadata;
Struct->GetStringMetaDataHierarchical(FRigVMStruct::CategoryMetaName, &CategoryMetadata);
Struct->GetStringMetaDataHierarchical(FRigVMStruct::DisplayNameMetaName, &DisplayNameMetadata);
Struct->GetStringMetaDataHierarchical(FRigVMStruct::MenuDescSuffixMetaName, &MenuDescSuffixMetadata);
if(DisplayNameMetadata.IsEmpty())
{
DisplayNameMetadata = Struct->GetDisplayNameText().ToString();
}
if (!MenuDescSuffixMetadata.IsEmpty())
{
MenuDescSuffixMetadata = TEXT(" ") + MenuDescSuffixMetadata;
}
FText MenuDesc = FText::FromString(DisplayNameMetadata + MenuDescSuffixMetadata);
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -0,0 +1,55 @@
# NodeColor
- **功能描述:** 指定FRigUnit蓝图节点的RGB颜色值。
- **使用位置:** USTRUCT
- **引擎模块:** RigVMStruct
- **元数据类型:** string="abc"
- **限制类型:** FRigUnit
- **常用程度:** ★★
指定FRigUnit蓝图节点的RGB颜色值。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName = "MyRigColor",NodeColor="1 0 0"))
struct INSIDER_API FRigUnit_MyRigColor: public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY(meta = (Input))
float MyFloat_Input = 123.f;
UPROPERTY(meta = (Output))
float MyFloat_Output = 123.f;
};
```
## 测试效果:
加上NodeColor之后颜色从左变成右。
![Untitled](Untitled.png)
## 原理:
从Meta中获取颜色值。
```cpp
FLinearColor FRigVMDispatchFactory::GetNodeColor() const
{
if(const UScriptStruct* ScriptStruct = GetScriptStruct())
{
FString NodeColor;
if (ScriptStruct->GetStringMetaDataHierarchical(FRigVMStruct::NodeColorMetaName, &NodeColor))
{
return FRigVMTemplate::GetColorFromMetadata(NodeColor);
}
}
return FLinearColor::White;
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -0,0 +1,11 @@
# Output
- **功能描述:** 指定FRigUnit下的该属性作为输出引脚。
- **使用位置:** UPROPERTY
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **限制类型:** FRigUnit中属性
- **关联项:** [Input](Input/Input.md)
- **常用程度:** ★★★★★
指定FRigUnit下的该属性作为输出引脚。

View File

@@ -0,0 +1,84 @@
# RigVMTypeAllowed
- **功能描述:** 指定一个UENUM可以在FRigUnit的UEnum*属性中被选择。
- **使用位置:** UENUM
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **常用程度:** ★★
指定一个UENUM可以在FRigUnit的UEnum*属性中被选择。
## 测试代码:
```cpp
UENUM(BlueprintType)
enum class ERigMyEnum : uint8
{
First,
Second,
Third,
};
UENUM(BlueprintType, meta = (RigVMTypeAllowed))
enum class ERigMyEnumAllowed : uint8
{
Cat,
Dog,
Tiger,
};
USTRUCT(meta = (DisplayName = "MyRigEnum"))
struct INSIDER_API FRigUnit_MyRigEnum : public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY(meta = (Input))
UEnum* MyEnum;
UPROPERTY(meta = (Output))
float MyFloat_Output = 123.f;
};
```
## 测试效果:
可见在选项列表中只有ERigMyEnumAllowed没有ERigMyEnum。
![Untitled](Untitled.png)
## 原理:
在生成选项的时候,判断 !Enum->IsAsset()说明是C++里的枚举然后必须有RigVMTypeAllowed。
```cpp
void SRigVMEnumPicker::PopulateEnumOptions()
{
EnumOptions.Reset();
EnumOptions.Add(MakeShareable(new FString(TEXT("None"))));
for (TObjectIterator<UEnum> EnumIt; EnumIt; ++EnumIt)
{
UEnum* Enum = *EnumIt;
if (Enum->HasAnyFlags(RF_BeginDestroyed | RF_FinishDestroyed) || !Enum->HasAllFlags(RF_Public))
{
continue;
}
// Any asset based enum is valid
if (!Enum->IsAsset())
{
// Native enums only allowed if contain RigVMTypeAllowed metadata
if (!Enum->HasMetaData(TEXT("RigVMTypeAllowed")))
{
continue;
}
}
EnumOptions.Add(MakeShareable(new FString(Enum->GetPathName())));
}
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 KiB

View File

@@ -0,0 +1,68 @@
# TemplateName
- **功能描述:** 指定该FRigUnit成为一个泛型模板节点。
- **使用位置:** USTRUCT
- **引擎模块:** RigVMStruct
- **元数据类型:** string="abc"
- **限制类型:** FRigUnit
- **常用程度:** ★★★
指定该FRigUnit成为一个泛型模板节点。
不同的FRigUnit在设置到同一个TemplateName 之后会分析其Input和Output的属性的整个函数签名最后分析出哪些属性是泛型引脚即同名不同类型的属性。在调用的时候输入的是TemplateNode即TemplateName 形成的节点。然后再手动连接引脚来确定最后的函数类型从而最后再完全确定应该实际应用到哪一个FRigUnit节点。
这个功能在实现一些逻辑相同但是参数类型稍微不同的时候会比较便利。往往FRigUnit_MyTemplate_Float和FRigUnit_MyTemplate_Int会继承于一个基类但不是强制在里面实现公用的逻辑或属性。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName = "Set My float", TemplateName = "SetMyTemplate"))
struct INSIDER_API FRigUnit_MyTemplate_Float : public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY(meta = (Input))
float MyValue;
UPROPERTY(meta = (Output))
FString MyStringResult;
};
USTRUCT(meta = (DisplayName = "Set My int", TemplateName = "SetMyTemplate"))
struct INSIDER_API FRigUnit_MyTemplate_Int : public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY(meta = (Input))
int32 MyValue;
UPROPERTY(meta = (Output))
FString MyStringResult;
};
```
## 测试效果:
可见一开始的节点是SetMyTemplate然后根据引脚类型的不同再实际Resolve成FRigUnit_MyTemplate_Float 或者是FRigUnit_MyTemplate_Int 。因为我没有实现SetMyString所以FString类型的是不能连接到引脚的。
![RigVM_Template](RigVM_Template.gif)
## 原理:
源码里涉及到这一块的代码比较多。大致逻辑是FRigUnit在初始化的时候注册到FRigVMRegistry里如果有TempalteName则创建一个FRigTemplate之后蓝图右键创建的时候实际创建的是URigTemplateNode然后再由FRigDispatch来分发到实际的最终节点。
```cpp
void FRigVMRegistry::Register(const TCHAR* InName, FRigVMFunctionPtr InFunctionPtr, UScriptStruct* InStruct, const TArray<FRigVMFunctionArgument>& InArguments)
{
FString TemplateMetadata;
if (InStruct->GetStringMetaDataHierarchical(TemplateNameMetaName, &TemplateMetadata))
{
}
}
```

View File

@@ -0,0 +1,9 @@
# Varying
- **功能描述:** ScriptStruct /Script/RigVM.RigVMFunction_GetDeltaTime
- **使用位置:** UCLASS
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **常用程度:** 0
放在USTRUCT上的时候发现用在IsDefinedAsVarying这种函数上但是F5没有发现调用的地方。

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1,87 @@
# Visible
- **功能描述:** 指定FRigUnit下的该属性为常量引脚无法连接变量。
- **使用位置:** UPROPERTY
- **引擎模块:** RigVMStruct
- **元数据类型:** bool
- **限制类型:** FRigUnit中属性
- **关联项:** [Input](../Input/Input.md)
- **常用程度:** ★★★
指定FRigUnit下的该属性为常量引脚无法连接变量。
Visible和Input+Constant的效果是一致的。
## 测试代码:
```cpp
USTRUCT(meta = (DisplayName = "MyRig"))
struct INSIDER_API FRigUnit_MyRig : public FRigUnit
{
GENERATED_BODY()
RIGVM_METHOD()
virtual void Execute() override;
public:
UPROPERTY()
float MyFloat_Normal;
UPROPERTY(meta = (Input))
float MyFloat_Input;
UPROPERTY(meta = (Output))
float MyFloat_Output;
UPROPERTY(meta = (Input, Output))
float MyFloat_IO;
UPROPERTY(meta = (Hidden))
float MyFloat_Hidden;
UPROPERTY(meta = (Visible))
float MyFloat_Visible;
UPROPERTY(meta = (Input, Constant))
float MyFloat_Constant;
};
```
## 测试效果:
Visible和Input+Constant的效果是一致的也是成为一个常量。
![Untitled](Untitled.png)
## 原理:
```cpp
UENUM(BlueprintType)
enum class ERigVMPinDirection : uint8
{
Input, // A const input value
Output, // A mutable output value
IO, // A mutable input and output value
Visible, // A const value that cannot be connected to
Hidden, // A mutable hidden value (used for interal state)
Invalid // The max value for this enum - used for guarding.
};
FRigVMPinInfo::FRigVMPinInfo(FProperty* InProperty, ERigVMPinDirection InDirection, int32 InParentIndex, const uint8* InDefaultValueMemory)
{
bIsConstant = InProperty->HasMetaData(TEXT("Constant"));
}
void URigVMController::ConfigurePinFromProperty(FProperty* InProperty, URigVMPin* InOutPin, ERigVMPinDirection InPinDirection) const
{
InOutPin->bIsConstant = InProperty->HasMetaData(TEXT("Constant"));
}
bool URigVMPin::CanBeBoundToVariable(const FRigVMExternalVariable& InExternalVariable, const FString& InSegmentPath) const
{
if (bIsConstant)
{
return false;
}
}
```