【UE4】蓝图转为C++官方教程部分笔记

动机

官方教学有将蓝图转为C++的教学视频,非常详细。
将蓝图转为C++ – Unreal Engine
为了方便查找知识点,特意在这里记了一部分笔记(图片都来自于本人的工程而非视频)

1. 蓝图和C++的变量对应

  • 想要实现C++和蓝图的转换,首先就得知道蓝图和C++的变量对应关系
  • 首先官方文档有的规定代码规范中,明确提出了类型前缀名:
    • 模板类的前缀为T。
      例:TArray
    • 继承自 UObject 的类前缀为U。
      例:UStaticMeshComponent*
    • 继承自 AActor 的类前缀为A。
      例:APlayerController
    • 继承自 SWidget 的类前缀为S。
    • 抽象界面类的前缀为I.
    • 列举的前缀为E。
    • 布尔变量必须以b为前缀(例如 bPendingDestruction 或 bHasFadedIn)。
    • 其他多数类均以F为前缀,而部分子系统则以其他字母为前缀。
蓝图 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++中实现,类似于我们学过的纯虚函数。

在这里插入图片描述

  • 同样是选择一个重载函数。

在这里插入图片描述

  • 这个函数就是更新HPBar这个血条控件,要知道这个控件实在蓝图里面才有定义的。
void ABaseCharacter::UpdateHealth(const float HealthAdd)
{
    
    
	NowHealth += HealthAdd ;
	if(NowHealth > MaxHealth) NowHealth =  MaxHealth;
	if(NowHealth < 0)
	{
    
    
		NowHealth = 0 ;
		Dead() ;
	}
	UpdateHPBar();
}
  • 调用函数还是刚才那个。

在这里插入图片描述

  • 血条正确更新!说明确实调用了蓝图事件。

蓝图本地事件VS蓝图可实现事件

蓝图本地事件 蓝图可实现事件
BlueprintNativeEvent BlueprintImplementableEvent
不可在C++中实现,只在蓝图实现 可以在C++中实现,蓝图不一定要实现
专门用于被重载 可以被重载,可以先执行C++部分再执行蓝图部分
  • 这两个宏的存在也就能让我们打消顾虑,在C++中写出主要逻辑。而涉及到资产引用,蓝图组件的都可以使用这两个方法创建函数来解决。

例子:

猜你喜欢

转载自blog.csdn.net/Alexander_420/article/details/124990760