虚幻UnrealEngine4 C++ 概念&Object类
序
虚幻引擎是全球最开放、最先进的实时3D创作平台。经过持续的改进,它已经不仅仅是一款殿堂级的游戏引擎,还能为各行各业的专业人士带去无限的创作*和空前的掌控力。无论是前沿内容、互动体验还是沉浸式虚拟世界,一切尽在虚幻引擎。
虚幻 UnrealEngine4的宏观的庞大、渲染的逼真、物理的真实,是众多游戏引擎所不能及的。蓝图的强大和易于上手,使其成为了可视化编程。但是作为程序员的我感觉不像是个程序员。因此,我在博客准备开始这个虚幻UnrealEngine4 C++ 基础专栏。从最基础的开始,逐步实现一个第三人称的RPG功能,从基础学习在虚幻 UnrealEngine4中使用C++开发游戏。
创建第一个C++工程
这里我们创建一个第三人称工程,命名为UECppBasicProject。
打开Unreal Engine 4 --> New Project --> C++ --> Third Person --> 修改 Folder目录 --> 编辑 Name名称 --> Creat Project
创建以后,会生产UECppBasicProject.uproject和UECppBasicProject.sln两个工程。
这里UE4工程不做过多介绍,简单说两句VS工程。VS工程中,会自动生产UECppBasicProjectCharacter和UECppBasicProjectGameMode类,UECppBasicProjectGameMode中没有多少代码可忽略。而UECppBasicProjectCharacter就是在游戏中,控制角色的代码类,先忽视这个类,后续我们逐步来完成一个自己编写的角色类,来逐步学习虚幻中C++基础。
虚幻中C++类关系概述
我用XMind整理了一下在UnrealEngine的World中,C++的关系图以及各个类的功能概述,但是展开后截图太大,这里简单截图看一下吧,想进一步了解,这里提供下载,自行看一下吧,都在个人对虚幻 UnrealEngine4理解,如果不对请大家包涵。
这我们从基础讲起,我们首先关注的类是Object、Actor、Pawn、Character,这里将逐步讲解。
虚幻的反射与垃圾回收
- 在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自动为我们生成相关代码。
// UE4规定,这里包含的 "XXX.generated.h" 要在所有的 include 的最后一个,后面不允许有 include了
#include "OneActor.generated.h"
// UCLASS 标记AOneActor要参与反射和垃圾回收
UCLASS()
class AOneActor : public AActor
{
// UPROPERTY 标记某个变量要参与反射和垃圾回收
UPROPERTY()
float OneFloat;
// UFUNCTION 标记某个函数要参与反射和垃圾回收
UFUNCTION()
void OneFunction();
};
// 在编译时,UE4会通过 UCLASS、UPROPERTY、UFUNCTION相关宏的定义 感知生成反射和垃圾回收的代码
GENERATED_CODE
...
需要明确一点:UCLASS/UFUNCTION/UPROPERTY等都不是真正有意义的C++宏,他们是UHT的标记,在经过UHT生成代码之后他们就是空宏了,没有意义。 UE的代码是把UHT标记和真正的宏都以宏的形式来表现,从结果来说,它们都是生成了一些代码,但是它们的处理流程不同。 UHT标记是先通过UHT进行扫描并生成代码,再通过编译器进行预处理等等,这里存在一个先后的过程,其限制就为:对UHT对代码的处理在前,编译器对宏的预处理在后,所以在UE中没办法用宏来包裹UHT标记。
创建第一个C++类和蓝图类
- 在Conternt Browser的C++ Classes中New C++ Class,让这个类继承最为基础的Object类。命名为OneObject。
创建成功后,我们可以在UE4和VS2017中看见OneObject相关内容。
- 第一个任务,把OneObject类创建一个蓝图类。但是默认是不允许的。
C++类和蓝图类的关系,你可以把它看成为,在C++中实现逻辑,而通过蓝图类添加到World中,观察表现。
如果想让OneObject类可以创建蓝图类。只需在UCLASS宏中添加以下代码即可 。
UCLASS(Blueprintable)
- 创建OneObject蓝图类BP_OneObject
创建成功后,会在UE4中看到,这个BP_OneObject蓝图编辑窗口。由于他继承了OneObject,OneObject继承了Object,因此这个蓝图类是无法加入到我们的场景中。
- 创建UObject的蓝图类与基础宏参数介绍
这里我们在OneObject,中编写代码,自己的变量和函数。使其可以在蓝图中被编辑和调用。
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "OneObject.generated.h"
UCLASS(Blueprintable)
class UECPPBASICPROJECT_API UOneObject : public UObject
{
GENERATED_BODY()
public:
UOneObject();
// 变量 蓝图中可被读写
UPROPERTY(BlueprintReadWrite)
float oneFloat;
// 函数 蓝图中可被调用
UFUNCTION(BlueprintCallable)
void oneFunction();
};
编译后,即可在蓝图中使用了。
- 通过宏给定义的变量和函数分类
再次修改代码,通过宏给定义的变量和函数分类,因为无法把BP_OneObject蓝图类拖放到场景中进行创建,这里我们在关卡蓝图初始化的时候,创建出BP_OneObject蓝图类并进行保存到关卡蓝图中,再进行变量的获取和调用。
OneObject.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "OneObject.generated.h"
/**
*
*/
UCLASS(Blueprintable)
class UECPPBASICPROJECT_API UOneObject : public UObject
{
GENERATED_BODY()
public:
UOneObject();
// 给相应的变量和函数添加类别
// 变量 蓝图中只被读
UPROPERTY(BlueprintReadOnly, Category = "OneObject Variables")
float oneFloat;
// 函数 蓝图中可被调用
UFUNCTION(BlueprintCallable, Category = "OneObject Funtions")
void oneFunction();
};
OneObject.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "OneObject.h"
UOneObject::UOneObject()
{
oneFloat = 0.0f;
}
void UOneObject::oneFunction()
{
UE_LOG(LogTemp, Log, TEXT("OneObject oneFunction!"));
// UE_LOG(LogTemp, Warning, TEXT("OneObject oneFunction!"))
// UE_LOG(LogTemp, Error, TEXT("OneObject oneFunction!"))
}
关卡蓝图
上一篇: PHP生成随机用户名和密码的实现代码
下一篇: 假如男人会生孩子!