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,19 @@
# BlueprintCallable
- **功能描述:** 暴露到蓝图中可被调用
- **元数据类型:** bool
- **引擎模块:** Blueprint
- **作用机制:** 在FunctionFlags增加[FUNC_BlueprintCallable](../../../../Flags/EFunctionFlags/FUNC_BlueprintCallable.md)
- **常用程度:** ★★★★★
## 测试代码:
```cpp
UFUNCTION(BlueprintCallable)
void MyFunc_BlueprintCallable() {}
```
## 效果展示:
![Untitled](Untitled.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -0,0 +1,14 @@
# BlueprintGetter
- **功能描述:** 指定该函数作为属性的自定义Get函数。
- **元数据类型:** bool
- **引擎模块:** Blueprint
- **作用机制:** 在Meta中加入[BlueprintGetter](../../../Meta/Blueprint/BlueprintGetter.md)在FunctionFlags加入[FUNC_BlueprintCallable](../../../Flags/EFunctionFlags/FUNC_BlueprintCallable.md)、[FUNC_BlueprintPure](../../../Flags/EFunctionFlags/FUNC_BlueprintPure.md)
- **常用程度:** ★★
指定该函数作为属性的自定义Get函数。
此说明符隐含BlueprintPure和BlueprintCallable。
更多可以参考UPROPERTY的BlueprintGetter

View File

@@ -0,0 +1,39 @@
# BlueprintImplementableEvent
- **功能描述:** 指定一个函数调用点,可以在蓝图中重载实现。
- **元数据类型:** bool
- **引擎模块:** Blueprint
- **作用机制:** 在FunctionFlags中增加[FUNC_Event](../../../../Flags/EFunctionFlags/FUNC_Event.md)、[FUNC_Native](../../../../Flags/EFunctionFlags/FUNC_Native.md)、[FUNC_BlueprintEvent](../../../../Flags/EFunctionFlags/FUNC_BlueprintEvent.md)
- **常用程度:** ★★★★★
指定一个函数调用点可以在蓝图中重载实现。是一种方便的用来实现C++来调用蓝图函数的方式。
蓝图中如果没提供实现,调用的话相当于调用空函数。
BlueprintImplementableEvent也要配合BlueprintCallable使用如果没加BlueprintCallable的话就只能在CPP里调用在蓝图会发现找不到Call Function的节点。
## 测试代码:
```cpp
//FunctionFlags: FUNC_Event | FUNC_Public | FUNC_BlueprintCallable | FUNC_BlueprintEvent
UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
void MyFunc_ImplementableEvent();
```
## 效果展示:
右键可添加自定义实现
![Untitled](Untitled.png)
## 原理:
在C++里调用的时候里面会FindFunctionChecked根据名字寻找。如果蓝图中有找到的话则会调用。如果在蓝图中直接调用则其实是会直接FindFunctionChecked查找蓝图中有定义的话则会被直接找到。
```cpp
void AMyFunction_Default::MyFunc_ImplementableEvent()
{
ProcessEvent(FindFunctionChecked(NAME_AMyFunction_Default_MyFunc_ImplementableEvent),NULL);
}
```

View File

@@ -0,0 +1,49 @@
# BlueprintNativeEvent
- **功能描述:** 可以在蓝图总覆盖实现但是也在C++中提供一个默认实现。
- **元数据类型:** bool
- **引擎模块:** Blueprint
- **作用机制:** 在FunctionFlags中增加[FUNC_Event](../../../../Flags/EFunctionFlags/FUNC_Event.md)、[FUNC_BlueprintEvent](../../../../Flags/EFunctionFlags/FUNC_BlueprintEvent.md)
- **常用程度:** ★★★★★
可以在蓝图总覆盖实现但是也在C++中提供一个默认实现。
需要在CPP中声明名称与主函数相同的附加函数但是末尾添加了_Implementation。如果未找到任何蓝图覆盖该自动生成的代码将调用“ [FunctionName]_Implementation”方法。一般用在OnXXX之类的函数上在C++提供实现这样如果蓝图中没有覆盖的时候就可以默认调用C++中默认实现版本。
BlueprintNativeEvent没加BlueprintCallable的话就只能在CPP里调用因此一般也要配合加上BlueprintCallable。
## 测试代码:
```cpp
//FunctionFlags: FUNC_Native | FUNC_Event | FUNC_Public | FUNC_BlueprintCallable | FUNC_BlueprintEvent
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void MyFunc_NativeEvent();
void AMyFunction_Default::MyFunc_NativeEvent_Implementation()
{
GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Red, "MyFunc_NativeEvent_Implementation");
}
```
## 效果展示:
![Untitled](Untitled.png)
## 原理:
在调用MyFunc_NativeEvent的时候内部FindFunctionChecked会根据名字查找如果在蓝图中有定义则会找到蓝图中的实现版本。否则的话则会找到execMyFunc_NativeEvent这个实现版本从而调用MyFunc_NativeEvent_Implementation。
```cpp
DEFINE_FUNCTION(AMyFunction_Default::execMyFunc_NativeEvent)
{
P_FINISH;
P_NATIVE_BEGIN;
P_THIS->MyFunc_NativeEvent_Implementation();
P_NATIVE_END;
}
void AMyFunction_Default::MyFunc_NativeEvent()
{
ProcessEvent(FindFunctionChecked(NAME_AMyFunction_Default_MyFunc_NativeEvent),NULL);
}
```

View File

@@ -0,0 +1,26 @@
# BlueprintPure
- **功能描述:** 指定作为一个纯函数一般用于Get函数用来返回值。
- **元数据类型:** bool
- **引擎模块:** Blueprint
- **作用机制:** 在FunctionFlags增加[FUNC_BlueprintCallable](../../../../Flags/EFunctionFlags/FUNC_BlueprintCallable.md)、[FUNC_BlueprintPure](../../../../Flags/EFunctionFlags/FUNC_BlueprintPure.md)
- **常用程度:** ★★★★★
指定作为一个纯函数一般用于Get函数用来返回值。
- 纯函数是指没有执行引脚的函数不是指const函数。
- 纯函数可以有多个返回值,用引用参数加到函数里就行。
- 不能用于void函数否则会报错“error : BlueprintPure specifier is not allowed for functions with no return value and no output parameters.”
## 测试代码:
```cpp
UFUNCTION(BlueprintPure)
int32 GetMyInt()const { return MyInt; }
private:
int32 MyInt;
```
## 效果展示:
![Untitled](Untitled.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,13 @@
# BlueprintSetter
- **功能描述:** 指定该函数作为属性的自定义Set函数。
- **元数据类型:** bool
- **引擎模块:** Blueprint
- **作用机制:** 在Meta中加入[BlueprintSetter](../../../Meta/Blueprint/BlueprintSetter.md)在FunctionFlags中加入[FUNC_BlueprintCallable ](../../../Flags/EFunctionFlags/FUNC_BlueprintCallable.md)
- **常用程度:** ★★
指定该函数作为属性的自定义Set函数。
此说明符隐含BlueprintCallable。
更多可以参考UPROPERTY的BlueprintSetter

View File

@@ -0,0 +1,32 @@
# CallInEditor
- **功能描述:** 可以在属性细节面板上作为一个按钮来调用该函数。
- **元数据类型:** bool
- **引擎模块:** Editor
- **作用机制:** 在Meta中增加[CallInEditor](../../../../Meta/Blueprint/CallInEditor.md)
- **常用程度:** ★★★★★
可以在属性细节面板上作为一个按钮来调用该函数。
该函数写在AActor或UObject子类里都是可以的只要有对应的属性细节面板。
注意这一般是处于Editor运行环境的。典型的例子是ASkyLight的Recapture按钮。因此函数里有时会调用编辑器环境下函数。但也要注意不要在runtime下混用了比较容易出错。
## 测试代码:
```cpp
UCLASS(Blueprintable, BlueprintType)
class INSIDER_API AMyFunction_Default :public AActor
{
public:
GENERATED_BODY()
public:
UFUNCTION(CallInEditor)
void MyFunc_CallInEditor(){}
};
```
## 蓝图展示:
![Untitled](Untitled.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -0,0 +1,106 @@
# SealedEvent
- **功能描述:** 无法在子类中覆盖此函数。SealedEvent关键词只能用于事件。对于非事件函数请将它们声明为static或final以密封它们。
- **元数据类型:** bool
- **引擎模块:** Behavior
- **作用机制:** 在FunctionFlags中添加[FUNC_Final](../../../../Flags/EFunctionFlags/FUNC_Final.md)
在源码里搜索:发现都是用在网络的函数上
![Untitled](Untitled.png)
## UHT中的处理
```cpp
//先识别符号
[UhtSpecifier(Extends = UhtTableNames.Function, ValueType = UhtSpecifierValueType.Legacy)]
private static void SealedEventSpecifier(UhtSpecifierContext specifierContext)
{
UhtFunction function = (UhtFunction)specifierContext.Type;
function.FunctionExportFlags |= UhtFunctionExportFlags.SealedEvent;
}
//再设置标记
// Handle the initial implicit/explicit final
// A user can still specify an explicit final after the parameter list as well.
if (automaticallyFinal || function.FunctionExportFlags.HasAnyFlags(UhtFunctionExportFlags.SealedEvent))
{
function.FunctionFlags |= EFunctionFlags.Final;
function.FunctionExportFlags |= UhtFunctionExportFlags.Final | UhtFunctionExportFlags.AutoFinal;
}
再验证:限定只能用在Event上
if (FunctionExportFlags.HasAnyFlags(UhtFunctionExportFlags.SealedEvent) && !FunctionFlags.HasAnyFlags(EFunctionFlags.Event))
{
this.LogError("SealedEvent may only be used on events");
}
if (FunctionExportFlags.HasAnyFlags(UhtFunctionExportFlags.SealedEvent) && FunctionFlags.HasAnyFlags(EFunctionFlags.BlueprintEvent))
{
this.LogError("SealedEvent cannot be used on Blueprint events");
}
```
## 测试代码:
```cpp
//Error: "SealedEvent may only be used on events"
UFUNCTION(SealedEvent)
void MyFunc_SealedEvent() {}
//Error: "SealedEvent cannot be used on Blueprint events"
UFUNCTION(BlueprintCallable,BlueprintImplementableEvent,SealedEvent)
void MyFunc_ImplementableEvent();
//Error: "SealedEvent cannot be used on Blueprint events"
UFUNCTION(BlueprintCallable,BlueprintNativeEvent,SealedEvent)
void MyFunc_NativeEvent();
```
因此无法用于普通的函数又无法用于蓝图中的Event。所以既是Event又不是BlueprintEvent的是什么看源码是只有网络的一些函数。
通过对比发现Sealed函数的区别是多了FUNC_Final的标记。但FUNC_Final又不一定必须要以SealedEvent才能添加exec或普通的BlueprintCallable函数都会添加。但是如果是vitural的函数就不会添加。在UHT中的原理是
```cpp
private static UhtParseResult ParseUFunction(UhtParsingScope parentScope, UhtToken token)
{
if (function.FunctionFlags.HasAnyFlags(EFunctionFlags.Net))
{
// Network replicated functions are always events, and are only final if sealed
scopeName = "event";
tokenContext.Reset(scopeName);
automaticallyFinal = false;
}
// If virtual, remove the implicit final, the user can still specifying an explicit final at the end of the declaration
if (function.FunctionExportFlags.HasAnyFlags(UhtFunctionExportFlags.Virtual))
{
automaticallyFinal = false;
}
// Handle the initial implicit/explicit final
// A user can still specify an explicit final after the parameter list as well.
if (automaticallyFinal || function.FunctionExportFlags.HasAnyFlags(UhtFunctionExportFlags.SealedEvent))
{
function.FunctionFlags |= EFunctionFlags.Final;
function.FunctionExportFlags |= UhtFunctionExportFlags.Final | UhtFunctionExportFlags.AutoFinal;
}
}
```
在自己的C++代码中测试发现在C++中怎么继承都不会触发编译错误。因此如果想拒绝被继承还是用C++标准是final关键字。在函数末尾加final。
E:\P4V\Engine\Source\Editor\KismetCompiler\Private\KismetCompiler.cpp
```cpp
const uint32 OverrideFlagsToCheck = (FUNC_FuncOverrideMatch & ~FUNC_AccessSpecifiers);
if ((Context.Function->FunctionFlags & OverrideFlagsToCheck) != (OverridenFunction->FunctionFlags & OverrideFlagsToCheck))
{
MessageLog.Error(*LOCTEXT("IncompatibleOverrideFlags_Error", "Overriden function is not compatible with the parent function @@. Check flags: Exec, Final, Static.").ToString(), Context.EntryPoint);
}
```
在编译的时候检测的是否是重载父类的函数但因为SealedEvent不作用于普通函数也不作用于BlueprintEvent因此感觉只能在C++中继承。

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB