92 lines
3.7 KiB
Markdown
Raw Normal View History

2024-10-12 17:19:46 +08:00
# DefaultToSelf
- **功能描述:** 用在函数上指定一个参数的默认值为Self值
- **使用位置:** UFUNCTION
- **引擎模块:** Blueprint
- **元数据类型:** bool
- **常用程度:** ★★★★★
使得在蓝图调用的时候更加的便利,当然也要根据这个函数的需要。
## 测试代码:
```cpp
UCLASS()
class INSIDER_API UMyFunctionLibrary_SelfPinTest :public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
static FString PrintProperty_Default(UObject* myOwner,FName propertyName);
UFUNCTION(BlueprintCallable,meta=(DefaultToSelf="myOwner"))
static FString PrintProperty_HasDefaultToSelf(UObject* myOwner,FName propertyName);
UFUNCTION(BlueprintCallable,meta=(DefaultToSelf="myOwner",hidePin="myOwner"))
static FString PrintProperty_HasDefaultToSelf_ButHide(UObject* myOwner,FName propertyName);
};
```
蓝图里的节点可以看出蓝图编译器会自动的把DefaultToSelf指定的函数参数自动的赋值到Self当然这个和手动的连到self本质是一样的。额外一点可以通过HidePin再隐藏掉这个函数参数这样就默认把该蓝图节点所在的蓝图对象Self当作第一个函数参数显得更加简洁一些。
![Untitled](Untitled.png)
如果是BlueprintPure也是可以的
![Untitled](Untitled%201.png)
## 原理:
蓝图中的函数调用在编译的时候会自动的创建SelfPin名字为Target)。如果该函数是静态函数或HideSelfPin的标记则会把SelfPin隐藏起来。其SelfPin的值就是当前蓝图运行时对象的值。因此DefaultToSelf的效果就是蓝图系统会自动的把这个参数的值赋值为被调用处的蓝图运行时对象相当于C++ this指针的效果
```cpp
bool UK2Node_CallFunction::CreatePinsForFunctionCall(const UFunction* Function)
{
UEdGraphPin* SelfPin = CreateSelfPin(Function);
// Renamed self pin to target
SelfPin->PinFriendlyName = LOCTEXT("Target", "Target");
}
UEdGraphPin* FBlueprintNodeStatics::CreateSelfPin(UK2Node* Node, const UFunction* Function)
{
// Chase up the function's Super chain, the function can be called on any object that is at least that specific
const UFunction* FirstDeclaredFunction = Function;
while (FirstDeclaredFunction->GetSuperFunction() != nullptr)
{
FirstDeclaredFunction = FirstDeclaredFunction->GetSuperFunction();
}
// Create the self pin
UClass* FunctionClass = CastChecked<UClass>(FirstDeclaredFunction->GetOuter());
// we don't want blueprint-function target pins to be formed from the
// skeleton class (otherwise, they could be incompatible with other pins
// that represent the same type)... this here could lead to a compiler
// warning (the GeneratedClass could not have the function yet), but in
// that, the user would be reminded to compile the other blueprint
if (FunctionClass->ClassGeneratedBy)
{
FunctionClass = FunctionClass->GetAuthoritativeClass();
}
UEdGraphPin* SelfPin = NULL;
if (FunctionClass == Node->GetBlueprint()->GeneratedClass)
{
// This means the function is defined within the blueprint, so the pin should be a true "self" pin
SelfPin = Node->CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Object, UEdGraphSchema_K2::PSC_Self, nullptr, UEdGraphSchema_K2::PN_Self);
}
else if (FunctionClass->IsChildOf(UInterface::StaticClass()))
{
SelfPin = Node->CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Interface, FunctionClass, UEdGraphSchema_K2::PN_Self);
}
else
{
// This means that the function is declared in an external class, and should reference that class
SelfPin = Node->CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Object, FunctionClass, UEdGraphSchema_K2::PN_Self);
}
check(SelfPin != nullptr);
return SelfPin;
}
```