动机
官方教学有将蓝图转为C++的教学视频,非常详细。
将蓝图转为C++ – Unreal Engine
为了方便查找知识点,特意在这里记了一部分笔记(图片都来自于本人的工程而非视频)
1. 蓝图和C++的变量对应
- 想要实现C++和蓝图的转换,首先就得知道蓝图和C++的变量对应关系
- 首先官方文档有的规定代码规范中,明确提出了类型前缀名:
- 模板类的前缀为T。
例:TArray - 继承自 UObject 的类前缀为U。
例:UStaticMeshComponent* - 继承自 AActor 的类前缀为A。
例:APlayerController - 继承自 SWidget 的类前缀为S。
- 抽象界面类的前缀为I.
- 列举的前缀为E。
- 布尔变量必须以b为前缀(例如 bPendingDestruction 或 bHasFadedIn)。
- 其他多数类均以F为前缀,而部分子系统则以其他字母为前缀。
- 模板类的前缀为T。
蓝图 | C++ |
---|---|
String | FString |
Name | FName |
Vector | FVector |
Rotator | FRotator |
Transform | FTransform |
- 这些就是常见的F类变量
蓝图 | C++ |
---|---|
Float | float |
Integer | int32 |
Integer64 | int64 |
Bool | bool |
- 值得一提的是,C++类型中的double,unsigned int在蓝图中都是没有对应的。
蓝图 | C++ |
---|---|
Object | UObject* |
Actor | AActor |
ActorComponent | UActorComponent* |
- 这种类型非常多,都是用指针的。只要清楚变量属于Actor还是组件,一般都能判断出来。
2. BlueprintPure
UFUNCTION(BlueprintPure)
FORCEINLINE float GetNowHealth() const{return NowHealth;}
- 在变量声明的时候加上BluepPure的宏,就可以创建一个蓝图中没有执行引脚的节点。
- 而这个FORCEINLINE是指内联函数。
- 这样就封装的很漂亮,变量也可以根据情况写在Private里面了。
3. 寻找蓝图节点对应C++ API的方法
- 这里用上一个博客的例子
- 现在想办法获取向量长度这个API
-
首先可以猜想,在蓝图中他输入是一个向量,可以先看FVector里是否有对应的函数。这次很好运,真的有。
-
但是也不是每次都可以猜出来的,那就看看蓝图这里是怎么定义的。
-
这里说来自Kismet数学库,这个和K2都是面向蓝图节点的库,不宜直接照搬到C++
- 去源码里面搜索这个Kismet数学库。
- 然后打开对应节点一看确实是调用了FVector的函数。那就直接用上。
4. 用C++结构体取代蓝图结构体
- 还是因为C++ 无法直接访问蓝图,所以一开始就应该做好创建C++ 结构体的准备。
- 首先创建一个Object的子蓝图,等会就是把这个修改成Struct
UCLASS()
class DOUBLEG_API UBag : public UObject
{
GENERATED_BODY()
};
- 默认的代码长这样
USTRUCT(BlueprintType)
struct DOUBLEG_API FBag
{
GENERATED_BODY()
};
-
修改一下他:
1.CLASS都修改成STRUCT
2.继承去掉
3.U类型改成F类型‘ -
这时候编译一下,我和他一样,UE4崩溃了。。。。
-
然后里面加入变量,操作就和普通蓝图一样了。
5. 蓝图本地事件和蓝图可实现事件
蓝图本地事件:在C++ 中声明,实现,并且可以在蓝图中调用和重载
UFUNCTION(BlueprintNativeEvent,BlueprintCallable)
void Dead();
- 例子:一个死亡函数
- 首先需要一个BlueprintNativeEvent的宏
void ABaseCharacter::Dead_Implementation()
{
GetMesh()->SetSimulatePhysics(true);
SetLifeSpan(1);
}
- 现在在.cpp里去实现就不再是用Dead()这个名字了,而是要加上_Implementation这个后缀才行。
- 打开子蓝图,在重载函数中找到他。
- 我们需要调用父类里的函数,所以就选择调用父类函数。
- 也就是说,直接覆盖也是可以的。
- 我们让单位死亡的时候不仅完成原本的操作,还进行一次输出。
void ABaseCharacter::UpdateHealth(const float HealthAdd)
{
NowHealth += HealthAdd ;
if(NowHealth > MaxHealth) NowHealth = MaxHealth;
if(NowHealth < 0)
{
NowHealth = 0 ;
Dead() ;
}
UpdateHPBar();
}
- 在C++ 中调用Dead函数(没有用蓝图调用)
- 成功!
- 这也就意味着,如果声明了一个蓝图本地事件,并且在子蓝图添加实现的话,在C++中调用这个函数就可以使用蓝图中的节点,一些C++中比较麻烦的操作可以规避掉了。
蓝图可实现事件:在C++ 中声明,在蓝图中实现
UFUNCTION(BlueprintImplementableEvent,BlueprintCallable)
void UpdateHPBar();
- 例子:更新血条的操作,因为C++中获取用户界面比较麻烦,所以选择蓝图可定义事件。
- 宏是BlueprintImplementableEvent
- 他不能在C++中实现,类似于我们学过的纯虚函数。
- 同样是选择一个重载函数。
文章来源:https://www.toymoban.com/news/detail-418086.html
- 这个函数就是更新HPBar这个血条控件,要知道这个控件实在蓝图里面才有定义的。
void ABaseCharacter::UpdateHealth(const float HealthAdd)
{
NowHealth += HealthAdd ;
if(NowHealth > MaxHealth) NowHealth = MaxHealth;
if(NowHealth < 0)
{
NowHealth = 0 ;
Dead() ;
}
UpdateHPBar();
}
- 调用函数还是刚才那个。
文章来源地址https://www.toymoban.com/news/detail-418086.html
- 血条正确更新!说明确实调用了蓝图事件。
蓝图本地事件VS蓝图可实现事件
蓝图本地事件 | 蓝图可实现事件 |
---|---|
BlueprintNativeEvent | BlueprintImplementableEvent |
不可在C++中实现,只在蓝图实现 | 可以在C++中实现,蓝图不一定要实现 |
专门用于被重载 | 可以被重载,可以先执行C++部分再执行蓝图部分 |
- 这两个宏的存在也就能让我们打消顾虑,在C++中写出主要逻辑。而涉及到资产引用,蓝图组件的都可以使用这两个方法创建函数来解决。
例子:
- 如果喜欢的话,可以看看我实操将官方模板蓝图改C++,希望对你有帮助。
【UE4】将蓝图转为C++的方法实操示范
到了这里,关于【UE4】蓝图转为C++官方教程部分笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!