vault backup: 2024-10-12 17:19:45
@@ -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;
|
||||
};
|
||||
```
|
||||
|
||||
## 测试效果:
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
在一些内部处理的时候,当然会略过这种抽象基类。
|
||||
|
||||
```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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
After Width: | Height: | Size: 15 KiB |
@@ -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的效果。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
识别该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;
|
||||
}
|
||||
```
|
After Width: | Height: | Size: 265 KiB |
@@ -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
|
||||
{
|
||||
}
|
||||
```
|
@@ -0,0 +1,60 @@
|
||||
# CustomWidget
|
||||
|
||||
- **功能描述:** 指定该FRigUnit里的属性要用自定义的控件来编辑。
|
||||
- **使用位置:** UPROPERTY
|
||||
- **引擎模块:** RigVMStruct
|
||||
- **元数据类型:** string="abc"
|
||||
- **限制类型:** FRigUnit中的属性
|
||||
- **常用程度:** ★★
|
||||
|
||||
指定该FRigUnit里的属性要用自定义的控件来编辑。
|
||||
|
||||
CustomWidget的值是在一些选项中选择的,这些自定义控件是已经在引擎中实现的。
|
||||
|
||||
可用的列表为:BoneName,ControlName,SpaceName/NullName,CurveName,ElementName,ConnectorName,DrawingName,ShapeName,AnimationChannelName,MetadataName,MetadataTagName。
|
||||
|
||||
测试代码里就只用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的列表。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
```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);
|
||||
}
|
||||
//等等其他
|
||||
}
|
||||
```
|
After Width: | Height: | Size: 68 KiB |
@@ -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;
|
||||
};
|
||||
```
|
||||
|
||||
## 测试效果:
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
在构建菜单项的时候略过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;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
@@ -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;
|
||||
```
|
||||
|
||||
## 测试效果:
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
根据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;
|
||||
}
|
||||
```
|
After Width: | Height: | Size: 58 KiB |
@@ -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默认状态下就把该结构展开。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
识别该Meta然后设定该引脚的bIsExpanded状态。
|
||||
|
||||
```cpp
|
||||
FRigVMPinInfo::FRigVMPinInfo(FProperty* InProperty, ERigVMPinDirection InDirection, int32 InParentIndex, const uint8* InDefaultValueMemory)
|
||||
{
|
||||
if (InProperty->HasMetaData(FRigVMStruct::ExpandPinByDefaultMetaName))
|
||||
{
|
||||
bIsExpanded = true;
|
||||
}
|
||||
}
|
||||
```
|
After Width: | Height: | Size: 35 KiB |
@@ -0,0 +1,9 @@
|
||||
# Hidden
|
||||
|
||||
- **功能描述:** 指定FRigUnit下的该属性隐藏
|
||||
- **使用位置:** UPROPERTY
|
||||
- **引擎模块:** RigVMStruct
|
||||
- **元数据类型:** bool
|
||||
- **限制类型:** FRigUnit中属性
|
||||
- **关联项:** [Input](Input/Input.md)
|
||||
- **常用程度:** ★★★
|
@@ -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函数目标。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
```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]);
|
||||
}
|
||||
}
|
||||
```
|
After Width: | Height: | Size: 176 KiB |
@@ -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一样,在蓝图节点和细节面板都隐藏起来,只是作为自己的内部值使用。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
根据属性上的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;
|
||||
}
|
||||
```
|
After Width: | Height: | Size: 310 KiB |
@@ -0,0 +1,61 @@
|
||||
# Keywords
|
||||
|
||||
- **功能描述:** 设定FRigUnit蓝图节点在右键菜单中的关键字,方便输入查找。
|
||||
- **使用位置:** USTRUCT
|
||||
- **引擎模块:** RigVMStruct
|
||||
- **元数据类型:** strings="a,b,c"
|
||||
- **限制类型:** 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中的字符的时候,也可以找到该节点。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
```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);
|
||||
|
||||
}
|
||||
```
|
After Width: | Height: | Size: 16 KiB |
@@ -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)"的后缀。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
得到该数据,然后添加到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);
|
||||
```
|
After Width: | Height: | Size: 22 KiB |
@@ -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之后,颜色从左变成右。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
从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;
|
||||
}
|
||||
|
||||
```
|
After Width: | Height: | Size: 32 KiB |
@@ -0,0 +1,11 @@
|
||||
# Output
|
||||
|
||||
- **功能描述:** 指定FRigUnit下的该属性作为输出引脚。
|
||||
- **使用位置:** UPROPERTY
|
||||
- **引擎模块:** RigVMStruct
|
||||
- **元数据类型:** bool
|
||||
- **限制类型:** FRigUnit中属性
|
||||
- **关联项:** [Input](Input/Input.md)
|
||||
- **常用程度:** ★★★★★
|
||||
|
||||
指定FRigUnit下的该属性作为输出引脚。
|
@@ -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。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
在生成选项的时候,判断 !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())));
|
||||
}
|
||||
}
|
||||
```
|
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 761 KiB |
@@ -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类型的是不能连接到引脚的。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
源码里涉及到这一块的代码比较多。大致逻辑是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))
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
@@ -0,0 +1,9 @@
|
||||
# Varying
|
||||
|
||||
- **功能描述:** ScriptStruct /Script/RigVM.RigVMFunction_GetDeltaTime
|
||||
- **使用位置:** UCLASS
|
||||
- **引擎模块:** RigVMStruct
|
||||
- **元数据类型:** bool
|
||||
- **常用程度:** 0
|
||||
|
||||
放在USTRUCT上的时候,发现用在IsDefinedAsVarying这种函数上,但是F5没有发现调用的地方。
|
After Width: | Height: | Size: 38 KiB |
@@ -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的效果是一致的,也是成为一个常量。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
```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;
|
||||
}
|
||||
}
|
||||
```
|