84 lines
3.0 KiB
Markdown
84 lines
3.0 KiB
Markdown
|
# RequiredInput
|
|||
|
|
|||
|
- **功能描述:** 在UMaterialExpression中指定FExpressionInput属性是否要求输入,引脚显示白色或灰色。
|
|||
|
- **使用位置:** UPROPERTY
|
|||
|
- **引擎模块:** Material
|
|||
|
- **元数据类型:** bool
|
|||
|
- **限制类型:** UMaterialExpression::FExpressionInput
|
|||
|
- **关联项:** [OverridingInputProperty](OverridingInputProperty/OverridingInputProperty.md)
|
|||
|
|
|||
|
在UMaterialExpression中指定FExpressionInput属性是否要求输入,引脚显示白色或灰色。
|
|||
|
|
|||
|
一般都配合OverridingInputProperty使用。
|
|||
|
|
|||
|
代码和效果参见OverridingInputProperty
|
|||
|
|
|||
|
## 原理:
|
|||
|
|
|||
|
```cpp
|
|||
|
|
|||
|
bool UMaterialExpression::CanEditChange(const FProperty* InProperty) const
|
|||
|
{
|
|||
|
bool bIsEditable = Super::CanEditChange(InProperty);
|
|||
|
if (bIsEditable && InProperty != nullptr)
|
|||
|
{
|
|||
|
// Automatically set property as non-editable if it has OverridingInputProperty metadata
|
|||
|
// pointing to an FExpressionInput property which is hooked up as an input.
|
|||
|
//
|
|||
|
// e.g. in the below snippet, meta=(OverridingInputProperty = "A") indicates that ConstA will
|
|||
|
// be overridden by an FExpressionInput property named 'A' if one is connected, and will thereby
|
|||
|
// be set as non-editable.
|
|||
|
//
|
|||
|
// UPROPERTY(meta = (RequiredInput = "false", ToolTip = "Defaults to 'ConstA' if not specified"))
|
|||
|
// FExpressionInput A;
|
|||
|
//
|
|||
|
// UPROPERTY(EditAnywhere, Category = MaterialExpressionAdd, meta = (OverridingInputProperty = "A"))
|
|||
|
// float ConstA;
|
|||
|
//
|
|||
|
|
|||
|
static FName OverridingInputPropertyMetaData(TEXT("OverridingInputProperty"));
|
|||
|
|
|||
|
if (InProperty->HasMetaData(OverridingInputPropertyMetaData))
|
|||
|
{
|
|||
|
const FString& OverridingPropertyName = InProperty->GetMetaData(OverridingInputPropertyMetaData);
|
|||
|
|
|||
|
FStructProperty* StructProp = FindFProperty<FStructProperty>(GetClass(), *OverridingPropertyName);
|
|||
|
if (ensure(StructProp != nullptr))
|
|||
|
{
|
|||
|
static FName RequiredInputMetaData(TEXT("RequiredInput"));
|
|||
|
|
|||
|
// Must be a single FExpressionInput member, not an array, and must be tagged with metadata RequiredInput="false"
|
|||
|
if (ensure( StructProp->Struct->GetFName() == NAME_ExpressionInput &&
|
|||
|
StructProp->ArrayDim == 1 &&
|
|||
|
StructProp->HasMetaData(RequiredInputMetaData) &&
|
|||
|
!StructProp->GetBoolMetaData(RequiredInputMetaData)))
|
|||
|
{
|
|||
|
const FExpressionInput* Input = StructProp->ContainerPtrToValuePtr<FExpressionInput>(this);
|
|||
|
|
|||
|
if (Input->Expression != nullptr && Input->GetTracedInput().Expression != nullptr)
|
|||
|
{
|
|||
|
bIsEditable = false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (bIsEditable)
|
|||
|
{
|
|||
|
// If the property has EditCondition metadata, then whether it's editable depends on the other EditCondition property
|
|||
|
const FString EditConditionPropertyName = InProperty->GetMetaData(TEXT("EditCondition"));
|
|||
|
if (!EditConditionPropertyName.IsEmpty())
|
|||
|
{
|
|||
|
FBoolProperty* EditConditionProperty = FindFProperty<FBoolProperty>(GetClass(), *EditConditionPropertyName);
|
|||
|
{
|
|||
|
bIsEditable = *EditConditionProperty->ContainerPtrToValuePtr<bool>(this);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return bIsEditable;
|
|||
|
}
|
|||
|
|
|||
|
```
|