124 lines
3.6 KiB
Markdown
Raw Normal View History

2024-10-12 17:19:46 +08:00
# RestrictedToClasses
- **功能描述:** 限制蓝图函数库下的函数只能在RestrictedToClasses指定的类蓝图中右键创建出来
- **使用位置:** UCLASS
- **引擎模块:** Blueprint
- **元数据类型:** strings="abc"
- **限制类型:** BlueprintFunctionLibrary
- **常用程度:** ★★★
在蓝图函数库上使用指定该函数库中的函数只能用在RestrictedToClasses指定的类的蓝图中不能在别的蓝图类中被右键出来。
## 测试代码:
```cpp
UCLASS(Blueprintable)
class INSIDER_API UMyClass_RestrictedToClasses :public UObject
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite,EditAnywhere)
float MyFloat;
};
UCLASS(meta=(RestrictedToClasses="MyClass_RestrictedToClasses"))
class INSIDER_API UMyClass_RestrictedToClassesLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
static float GetMyClassRestrictedFloat(UMyClass_RestrictedToClasses* myObject) {return myObject->MyFloat;}
};
```
在UMyClass_RestrictedToClasses 的子类蓝图中测试效果:
![Untitled](Untitled.png)
在别的地方,比如关卡蓝图中测试效果:
因此右键创建不出来,但是直接粘贴节点其实还是可以调用的。
![Untitled](Untitled%201.png)
## 源码中的例子:
指定UBTFunctionLibrary中的节点只能在BTNode中使用否则没有意义。
```cpp
UCLASS(meta=(RestrictedToClasses="BTNode"), MinimalAPI)
class UBTFunctionLibrary : public UBlueprintFunctionLibrary
{
UFUNCTION(BlueprintPure, Category="AI|BehaviorTree", Meta=(HidePin="NodeOwner", DefaultToSelf="NodeOwner"))
static AIMODULE_API UBlackboardComponent* GetOwnersBlackboard(UBTNode* NodeOwner);
//....
}
```
## 原理:
```cpp
static bool BlueprintActionFilterImpl::IsRestrictedClassMember(FBlueprintActionFilter const& Filter, FBlueprintActionInfo& BlueprintAction)
{
bool bIsFilteredOut = false;
FBlueprintActionContext const& FilterContext = Filter.Context;
if (UClass const* ActionClass = BlueprintAction.GetOwnerClass())
{
if (ActionClass->HasMetaData(FBlueprintMetadata::MD_RestrictedToClasses))
{
FString const& ClassRestrictions = ActionClass->GetMetaData(FBlueprintMetadata::MD_RestrictedToClasses);
// Parse the the metadata into an array that is delimited by ',' and trim whitespace
TArray<FString> ParsedClassRestrictions;
ClassRestrictions.ParseIntoArray(ParsedClassRestrictions, TEXT(","));
for (FString& ValidClassName : ParsedClassRestrictions)
{
ValidClassName = ValidClassName.TrimStartAndEnd();
}
for (UBlueprint const* TargetContext : FilterContext.Blueprints)
{
UClass* TargetClass = TargetContext->GeneratedClass;
if(!TargetClass)
{
// Skip possible null classes (e.g. macros, etc)
continue;
}
bool bIsClassListed = false;
UClass const* QueryClass = TargetClass;
// walk the class inheritance chain to see if this class is one
// of the allowed
while (!bIsClassListed && (QueryClass != nullptr))
{
FString const ClassName = QueryClass->GetName();
// If this class is on the list of valid classes
for (const FString& ValidClassName : ParsedClassRestrictions)
{
bIsClassListed = (ClassName == ValidClassName);
if (bIsClassListed)
{
break;
}
}
QueryClass = QueryClass->GetSuperClass();
}
// if the blueprint class wasn't listed as one of the few
// classes that this can be accessed from, then filter it out
if (!bIsClassListed)
{
bIsFilteredOut = true;
break;
}
}
}
}
return bIsFilteredOut;
}
```