暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

虚幻UnrealEngine4 C++ 概念&Object类

林元皓 2020-02-12
472

虚幻引擎是全球最开放、最先进的实时3D创作平台。经过持续的改进,它已经不仅仅是一款殿堂级的游戏引擎,还能为各行各业的专业人士带去无限的创作自由和空前的掌控力。无论是前沿内容、互动体验还是沉浸式虚拟世界,一切尽在虚幻引擎。

虚幻 UnrealEngine4的宏观的庞大、渲染的逼真、物理的真实,是众多游戏引擎所不能及的。蓝图的强大和易于上手,使其成为了可视化编程。但是作为程序员的我感觉不像是个程序员。因此,我在博客准备开始这个虚幻UnrealEngine4 C++ 基础专栏。从最基础的开始,逐步实现一个第三人称的RPG功能,从基础学习在虚幻 UnrealEngine4中使用C++开发游戏。

创建第一个C++工程

这里我们创建一个第三人称工程,命名为UECppBasicProject

打开Unreal Engine 4 --> New Project --> C++ --> Third Person --> 修改 Folder目录 --> 编辑 Name名称 --> Creat Project


创建以后,会生产UECppBasicProject.uprojectUECppBasicProject.sln两个工程。

这里UE4工程不做过多介绍,简单说两句VS工程。VS工程中,会自动生产UECppBasicProjectCharacter和UECppBasicProjectGameMode类,UECppBasicProjectGameMode中没有多少代码可忽略。而UECppBasicProjectCharacter就是在游戏中,控制角色的代码类,先忽视这个类,后续我们逐步来完成一个自己编写的角色类,来逐步学习虚幻中C++基础。


虚幻中C++类关系概述

我用XMind整理了一下在UnrealEngineWorld中,C++的关系图以及各个类的功能概述,但是展开后截图太大,这里简单截图看一下吧,想进一步了解,这里提供下载,自行看一下吧,都在个人对虚幻 UnrealEngine4理解,如果不对请大家包涵。


这我们从基础讲起,我们首先关注的类是ObjectActorPawnCharacter,这里将逐步讲解。


虚幻的反射与垃圾回收

  • 在java和C#中,有着自己的反射和垃圾回收机制,但是在C++中没有,不过虚幻中实现了反射(Reflection)和垃圾回收(Garbage Collection)。如果你对RTTR感兴趣,可以看看这个开源项目,在 C++ 中加入反射式编程 RTTR。这里只对虚幻的反射和垃圾回收的使用做讲解,如果以后有时间会对反射与蓝图做讲解,又是个庞大的话题... 这里要提及到 UBT&UHT in UE4。 UBT(Unreal Build Tool)和UHT(Unreal Header Tool)与UE4的编译过程有关,尤其是.generated.h和.gen.cpp的生成。我们需要在需要反射和垃圾回收的类、函数、变量中加入专有的头文件和宏。从而关联上UHT,从而UE4自动为我们生成相关代码。

  1. // UE4规定,这里包含的 "XXX.generated.h" 要在所有的 include 的最后一个,后面不允许有 include了

  2. #include "OneActor.generated.h"


  3. // UCLASS 标记ANewActor要参与反射和垃圾回收

  4. UCLASS()

  5. class AOneActor : public AActor

  6. {

  7. // UPROPERTY 标记某个变量要参与反射和垃圾回收

  8. UPROPERTY()

  9. float OneFloat;


  10. // UFUNCTION 标记某个函数要参与反射和垃圾回收

  11. UFUNCTION()

  12. void OneFunction();

  13. };


  14. // 在编译时,UE4会通过 UCLASS、UPROPERTY、UFUNCTION相关宏的定义 感知生成反射和垃圾回收的代码

  15. GENERATED_CODE

  16. ...

需要明确一点:UCLASS/UFUNCTION/UPROPERTY等都不是真正有意义的C++宏,他们是UHT的标记,在经过UHT生成代码之后他们就是空宏了,没有意义。UE的代码是把UHT标记和真正的宏都以宏的形式来表现,从结果来说,它们都是生成了一些代码,但是它们的处理流程不同。 UHT标记是先通过UHT进行扫描并生成代码,再通过编译器进行预处理等等,这里存在一个先后的过程,其限制就为:对UHT对代码的处理在前,编译器对宏的预处理在后,所以在UE中没办法用宏来包裹UHT标记。

创建第一个C++类和蓝图类

  • Conternt BrowserC++ ClassesNew C++ Class,让这个类继承最为基础的Object类。命名为OneObject


创建成功后,我们可以在UE4和VS2017中看见OneObject相关内容。


  • 第一个任务,把OneObject类创建一个蓝图类。但是默认是不允许的。


C++类和蓝图类的关系,你可以把它看成为,在C++中实现逻辑,而通过蓝图类添加到World中,观察表现。如果想让OneObject类可以创建蓝图类。只需在UCLASS宏中添加以下代码即可 。

  1. UCLASS(Blueprintable)

  • 创建OneObject蓝图类BPOneObject 创建成功后,会在UE4中看到,这个BPOneObject蓝图编辑窗口。由于他继承了OneObjectOneObject继承了Object,因此这个蓝图类是无法加入到我们的场景中。


  • 创建UObject的蓝图类与基础宏参数介绍 这里我们在OneObject,中编写代码,自己的变量和函数。使其可以在蓝图中被编辑和调用。

  1. #pragma once


  2. #include "CoreMinimal.h"

  3. #include "UObject/NoExportTypes.h"

  4. #include "OneObject.generated.h"


  5. UCLASS(Blueprintable)

  6. class UECPPBASICPROJECT_API UOneObject : public UObject

  7. {

  8. GENERATED_BODY()


  9. public:

  10. UOneObject();


  11. // 变量 蓝图中可被读写

  12. UPROPERTY(BlueprintReadWrite)

  13. float oneFloat;

  14. // 函数 蓝图中可被调用

  15. UFUNCTION(BlueprintCallable)

  16. void oneFunction();

  17. };

编译后,即可在蓝图中使用了。


  • 通过宏给定义的变量和函数分类 再次修改代码,通过宏给定义的变量和函数分类,因为无法把BPOneObject蓝图类拖放到场景中进行创建,这里我们在关卡蓝图初始化的时候,创建出BPOneObject蓝图类并进行保存到关卡蓝图中,再进行变量的获取和调用。

OneObject.h

  1. // Fill out your copyright notice in the Description page of Project Settings.


  2. #pragma once


  3. #include "CoreMinimal.h"

  4. #include "UObject/NoExportTypes.h"

  5. #include "OneObject.generated.h"


  6. /**

  7. *

  8. */

  9. UCLASS(Blueprintable)

  10. class UECPPBASICPROJECT_API UOneObject : public UObject

  11. {

  12. GENERATED_BODY()


  13. public:

  14. UOneObject();


  15. // 给相应的变量和函数添加类别

  16. // 变量 蓝图中只被读

  17. UPROPERTY(BlueprintReadOnly, Category = "OneObject Variables")

  18. float oneFloat;

  19. // 函数 蓝图中可被调用

  20. UFUNCTION(BlueprintCallable, Category = "OneObject Funtions")

  21. void oneFunction();

  22. };

OneObject.cpp

  1. // Fill out your copyright notice in the Description page of Project Settings.



  2. #include "OneObject.h"


  3. UOneObject::UOneObject()

  4. {

  5. oneFloat = 0.0f;

  6. }


  7. void UOneObject::oneFunction()

  8. {

  9. UE_LOG(LogTemp, Log, TEXT("OneObject oneFunction!"));

  10. // UE_LOG(LogTemp, Warning, TEXT("OneObject oneFunction!"))

  11. // UE_LOG(LogTemp, Error, TEXT("OneObject oneFunction!"))

  12. }

关卡蓝图


文章转载自林元皓,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论