2017-05-18 12:12:35 qq_31828929 阅读数 825
  • 从这里开始虚幻4-Editor介绍 v4.18

    本课程系列取名英译系列,是录制人员参考国外英文原版经典教程,结合中国人的习惯录制而成。希望能够给大家以帮助。从这里开始虚幻4系列教程,是Unreal的官方发布的入门教学,非常经典,是学习Unreal的佳入口。

    2373 人正在学习 去看看 杨石兴

热重载

如您习惯于使用 C++ 在其他项目中编程,虚幻引擎的一个炫酷功能可能会让您小吃一惊。无需关闭编辑器即可对 C++ 变更进行编译!有两种方法实现:

在编辑器仍在运行时直接以普通方式从 Visual Studio 或 Xcode 进行编译。编辑器将检测到新编译的 DLL 文件并即时重载变更!
这里写图片描述
如与调试器存在附着,则需要先分离,方可通过 Visual Studio 进行编译。
或者,直接点击编辑器主工具栏上的 Compile 按钮。
这里写图片描述
此功能可用于此教程之后的部分。

通过蓝图延展 C++ 类

迄今为止,我们已通过 C++ 类向导创建了一个简单的游戏性类,并添加了一些供设计师设置的属性。现在我们一起来了解设计师应该如何从零开始创建唯一类。

首先我们需要从 AMyActor 类新建一个蓝图类。注意下图中选中的基类名显示为 MyActor,而非 AMyActor。这是刻意设置的结果。对设计师隐藏工具使用的命名规则,使命名更加浅显易懂。
这里写图片描述
按下 Select 后,便将新建一个默认命名的蓝图类。在此例中,如下方的 内容浏览器 截图所示 - 命名被设为 CustomActor1。

这是我们以设计师身份进行自定义的第一个类。首先我们需要变更伤害属性的默认值。在此例中,设计师将 TotalDamage 改为 300,将输出该伤害的时间设为 2 秒。这便是属性现在出现的方式。

这里写图片描述
我们的计算值与期望的数值不匹配。它应该为 150,但却仍然为默认的 200。出现此现象的原因是 - 属性从载入过程被初始化后,才会对每秒伤害数值进行计算。虚幻编辑器中的运行时变更并非原因所在。因为目标对象在编辑器中被更改时引擎将对其进行通知,所以该问题拥有简单的解决方法。以下代码显示派生值在编辑器中发生变化时进行计算所需要添加的钩。

void AMyActor::PostInitProperties()
{
    Super::PostInitProperties();

    CalculateValues();
}

void AMyActor::CalculateValues()
{
    DamagePerSecond = TotalDamage / DamageTimeInSeconds;
}

#if WITH_EDITOR
void AMyActor::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
    CalculateValues();

    Super::PostEditChangeProperty(PropertyChangedEvent);
}
#endif

需要注意的一点是 - PostEditChangeProperty() 法存在于编辑器特有的 #ifdef 中。这是为了用游戏必需的代码进行游戏构建,并删除使可执行文件容量无谓变大的多余代码。将代码编译后,如下图所示,DamagePerSecond 数值与期望值达成匹配。

这里写图片描述

跨 C++ 和蓝图边界调用函数

我们已经谈到如何对蓝图公开属性,在深入探索引擎之前还有最后一个需要介绍的要点。在游戏性系统的创建中,设计师需要调用 C++ 程序员创建的函数,而游戏性程序员需要从 C++ 代码调用蓝图中实现的函数。首先,我们先实现从蓝图中调用 CalculateValues() 函数。对蓝图公开函数和公开属性同样简单。在函数声明前放置一个宏即可!以下代码片段显示了所需内容。

UFUNCTION(BlueprintCallable, Category=”Damage”)
void CalculateValues();
UFUNCTION() 宏把 C++ 函数对反射系统公开。BlueprintCallable 选项将其对蓝图虚拟机公开。每个对蓝图公开的函数都需要与其相关的类型,右键单击快捷菜单才能正常使用。下图显示了类型对快捷菜单的影响。
这里写图片描述
如您所见,可从 Damage 类型选择函数。以下蓝图代码显示 TotalDamage 数值发生变化后将进行调用,重新计算依赖数据。
这里写图片描述
计算依赖属性使用的函数与之前添加的函数相同。引擎的大部分通过 UFUNCTION() 宏对蓝图公开,开发者无需编写 C++ 代码即可构建游戏。然而,最佳方法是使用 C++ 构建基础游戏性系统和与性能关系密切的代码,而蓝图则用于自定义行为或从 C++ 构建块创建合成行为。

实现设计师调用 C++ 代码的操作后,我们来寻找一个越过 C++/蓝图边界的好方法。此方法允许 C++ 代码调用蓝图中定义的函数。通常使用此方法告知设计师在适当时可进行反馈的事件。通常这包括特效生成或其他视觉效果,如 actor 的隐藏和现身。以下代码片段显示蓝图实现的函数。

UFUNCTION(BlueprintImplementableEvent, Category="Damage")
void CalledFromCpp();

此函数的调用方式和其他 C++ 函数相同。虚幻引擎在后台生成一个基础 C++ 函数实现;它理解如何调入蓝图 VM。这通常被称作 Thunk(形实转换程序)。如讨论中的蓝图不为此方法提供函数主体,函数的行为则与不含主体行为的 C++ 函数一样:不执行任何操作。如果希望提供 C++ 默认实现,同时仍允许蓝图覆写此方法,结果会怎样?UFUNCTION() 宏也拥有针对此情况的选项。以下代码片段显示达成此效果需要在头中进行的的变更。

UFUNCTION(BlueprintNativeEvent, Category="Damage")
void CalledFromCpp();

此版本仍然生成 thunking 法,以调入蓝图 VM。那么如何提供默认实现呢?工具还将生成外观与 _Implementation() 相似的新函数实现。您必须提供函数的这个版本,否则项目将无法链接。以下是上方声明的实现代码。

void AMyActor::CalledFromCpp_Implementation()
{
    // 玩点花活
}

现在,讨论中的蓝图不覆写方法时将调用函数的这个版本。需要注意:在编译工具的旧版本中,_Implementation() 声明为自动生成。在 4.8 或更高版本中,这会被显式添加到头中。

了解常规游戏性程序员工作流以及协同设计师构建游戏性功能的方法后,您便可以开始自己的游戏开发冒险之旅。您可继续阅读此文档了解如何在引擎中使用 C++,也可直接对 launcher 中的实例进行操作,获得实际操作经验。

2019-11-04 17:52:11 qq_44718259 阅读数 9
  • 从这里开始虚幻4-Editor介绍 v4.18

    本课程系列取名英译系列,是录制人员参考国外英文原版经典教程,结合中国人的习惯录制而成。希望能够给大家以帮助。从这里开始虚幻4系列教程,是Unreal的官方发布的入门教学,非常经典,是学习Unreal的佳入口。

    2373 人正在学习 去看看 杨石兴

004.C++里有哪几种数据类型?
答:
大致分为三大类:
一是基本类型,基本类型又包括整型,字符型(char),浮点型,布尔型(bool)。
而整型包括短整型(short int),整型(int),长整型(long int);
浮点型包括单精度型(float),双精度型(double),长双精度型(long double)。

二是派生类型,派生类型又包括指针类型(*),枚举类型(enum),数组类型([]),结构体类型(struct),共用体类型(union),类类型(class)。

三是空类型(void)。

C++中数据类型分为两种,简单类型和结构类型。
简单类型包括,整数类型,字符类型,浮点类型,指针类型,枚举类型和void类型。
结构类型包括数组,字符串,记录和文件。
C++中基本的数据类型包括,整数类型,浮点类型,和 void类型。

005.整型有哪几种形式?各种形式有什么区别?
答:
整型主要分为整数类型,字符类型,布尔类型

32位计算机形式分别为
1.int和无符号整型unsigned int 占用 4个字节;
2.short和无符号短整型unsigned short 占用 2个字节;
3.long和无符号长整型unsigned long 占用 4个字节;
4.char和无符号字符型unsigned char 占用 1个字节;
5.bool布尔类型 默认是false 占用1个字节。

根据类型名,长度和表示范围不同有划分为好多种。

006.C++中有哪些常量?
答:
整型常量,字符型常量,浮点型常量,字符串常量,地址常量,转义序列常量。

007.常量与变量有哪些区别?
答:
常量是不可以改变值的量,常量在定义的时候必须初始化,常量不可以寻地址,它的地址不允许赋给非常量指针。
变量是可以改变值的量,变量在定义的时候可以不用初始化,变量可以寻址。常量具有较高的编译执行效率。

008.操作符有哪些分类?
算术操作符;移位操作符;位操作符;赋值操作符;关系操作符;逻辑操作符;条件操作符;逗号操作符;单目操作符;双目操作符;三目操作符。

009.操作符优先级对运算符有什么影响?
答:
优先级规定操作数的结合方式,但并未说明操作数的计算顺序
结合性规定了具有相同优先级的运算符如何进行分组
当不同的运算符混合运算时,运算顺序是根据运算符的优先级而定的,优先级高的运算符先运算,优先级低的运算符后运算。在一个表达式中,如果各运算符有相同的优先级,运算顺序是从左向右,还是从右向左,是由运算符的结合性确定的。所谓结合性是指运算符可以和左边的表达式结合,也可以与右边的表达式结合。

010.逻辑操作与其他操作的关系?
位运算是将运算符两边的数字换算成二进制(例:0000010001)后比较相同位置上的0、1进行运算的。逻辑运算即比较运算符两边的逻辑值(true或false)。
作用
逻辑运算的作用相信大家都知道,下边来介绍下位运算的作用:
一、按位与 &
1、 清零特定位 (mask中特定位置0,其它位为1,s=s&mask) s=s&mask
2、取某数中指定位 (mask中特定位置1,其它位为0,s=s&mask) s=s&mask
二、按位或 |
常用来将源操作数某些位置1,其它位不变
三、按位异或
1、使特定位的值取反 (mask中特定位置1,其它位为0 s=s^mask)
2、把一个数自清零,如 a=a xor a 不管a是多少,最后a都等于零

逻辑操作(&,|,^)与条件操作(&&,||)的区别 ??
a.条件操作只能操作布尔型的,而逻辑操作不仅可以操作布尔型,而且可以操作数值型
b.逻辑操作不会产生短路.

011.自增自减前操作与后操作的区别?
1.前操作符是先自增自减再参与运算,后操作符是先运算再自增自减
2.前操作符返回的是变量本身,是个左值,后操作符返回的是临时变量是个右值

012.指针自增与自减有什么不同?
首先先明白几个基础点:

  1. 指针变量是没有乘除运算的;
  2. 指针变量是地址,指针变量的加减是地址的加减;
  3. *也是一个运算符;
    在这里插入图片描述

013.什么是左值和右值?
通俗的讲,左值就是能够出现在赋值符号左面的东西,而右值就是那些可以出现在赋值符号右面的东西了。

举个很简单的例子:

a=b+100;

那么这里a就是左值,b+25就是一个右值。左值和右值之间是不一定都能互换的,上面的这个例子就是不能互换的,如果写成

b+100=a;

大家都能看出来这样写会不编译通过的,因为编译器无法判断b+100的内存地址,所以不能操作。

看了这个例子,可以做一个总结,左值必须应该是一个变量或者是表达式等,但是它的物理位置是可以确定的,而右值不一定,这也是它们两者之间的区别。

关于左值是表达式的例子有数组,还有指针这些都可以。
014.什么是变量?
1变量代表内存中具有特定属性的一个存储单元,它用来存放数据,也就是变量的值,在程序运行期间,这样的值是可以改变的。
2变量名
一个变量有一个名字,以便引用。变量由字母、数字、下划线组成,并且第一个字符不能是数字。变量名区分大小写,大写与小写是两个不同的变量。
3变量的定义
C语言中,对所用变量强制定义,也就是“先定义,后使用”,没有定义的变量不能使用。
4变量类型
指定每一个变量属于一个类型,以便在编译时检错合纠错时更加方便。

015.变量有哪几种初始化方式?
变量初始化方式有如下两种:

  1. 在宣告变量时初始化
  2. 在构造函数里初始化
    016.变量默认初始化有什么规则?
    定义没有初始化式的变量时,系统有时候会帮我们初始化变量。系统如何初始化取决于变量的类型以及变量定义的位置。
      1、内置类型变量是否自动初始化取决于变量定义的位置。函数体外定义的变量初始成0;函数体内定义的变量不进行自动初始化。除了用作赋值操作的左操作数,其他任何使用未初始化变量的行为都是未定义的,不要依赖未定义行为。
     2、类类型变量在定义时,如果没有提供初始化式,则会自动调用默认构造函数进行初始化(不论变量在哪里定义)。如果某类型没有默认构造函数,则定义该类型对象时必须提供显示初始化式。
    定义数组时,如果没有显示提供初始化列表,则数组元素的自动化初始规则同普通变量一样:函数体外定义的内置类型数组,其元素初始为0;函数体内定义的内置类型数组,其元素无初始化;类类型数组无论在哪里定义,皆调用默认构造函数进行初始化,无默认构造函数则必须提供显示初始化列表。

如果定义数组时,仅提供了部分元素的初始列表,其剩下的数组元素,若是类类型则调用默认构造函数进行初始,若是内置类型则初始为0(不论数组定义位置)。

对于动态分配的数组,如果数组元素是内置类型,其元素无初始化;如果数组元素是类类型,依然调用默认构造函数进行初始化。也可以在使用跟在数组长度后面的一对空圆括号对数组元素做值初始化。

例如: int *ptrA = new int[10];

int *ptrB = new int[10] ();

其中ptrA指向的动态数组其元素未初始化,而ptrB指向的动态数组元素被初始化为0。

3、对于动态分配的单个对象,可使用直接初始化的语法规则在定义时显示初始化。如果不提供显示初始化式,动态创建的对象与在函数内部定义的变量初始化方式相同(即:内置类型无初始化,类类型调用默认构造函数进行初始化)。

2016-11-21 23:30:27 u013131744 阅读数 4615
  • 从这里开始虚幻4-Editor介绍 v4.18

    本课程系列取名英译系列,是录制人员参考国外英文原版经典教程,结合中国人的习惯录制而成。希望能够给大家以帮助。从这里开始虚幻4系列教程,是Unreal的官方发布的入门教学,非常经典,是学习Unreal的佳入口。

    2373 人正在学习 去看看 杨石兴

首先要说的是,游戏开发是一项高度复杂的代码开发工作,编程语言只是最基本的知识,它涉及的内容还有计算机图形学、3D数学、物理学等复杂的学科。但是若需要学完这么多知识才能开发游戏,恐怕许多人都已经断气了,更谈不上开发游戏了。所以前人就把各种复杂的代码封装起来,使得一般的游戏开发者可以更加接近游戏的逻辑和功能性方面的代码,而无需接触最底层的知识。

194023hhhqhbpcqpmpltad

所以说游戏引擎,可以是引擎开发者已经写好的一堆代码框架,使得我们可以去调用这些底层代码,也可以是像虚幻4还附带可视化关卡编辑器的工具(Unity3D也是可视化的游戏引擎,后面会谈当今主流游戏引擎的对比)。

为什么选用虚幻4引擎?

首先,现在流行而且出名的商业引擎主要有cocos2dx,Unity3D,UE4,CryEngine等。但是这里选择UE4,也有笔者认为的独特优势。

1) UE4是开源的。开源就是代码是完全开放的,为什么开源如此重要?一方面是因为只有我们看到源代码的实现细节,当出错了我们才能快速准确地判断出错的成因,节省被错误折腾的时间。(你想想像Unity3D这种闭源引擎,要是出错了,你是完全看不到为什么会发生错误的。除了不断盲目Debug,查文档和谷歌之外自己对于错误束手无策。)另一方面,开源可以使得我们深入学习引擎的原理,只知其然不知其所以然必然不能走得太远,而且会走得更痛苦。

2) UE4的画质是世界上数一数二的。游戏的画质往往由游戏引擎来决定的,一个好的游戏引擎它可以模拟出极度逼真或者极具美感的画面。读者可以自己去看看Unity3D制作的游戏和UE4制作的游戏,其精美程度是相差甚远的。(这里并不是完全指责Unity3D,毕竟它们面对的是不同的层次。)作为一名追求极致的游戏程序员,当然要想看看最好的效果是怎么实现的。

3) UE4免费!无需多言,还有比免费更好的事吗?

下图为UE4游戏引擎制作出来的极度逼真游戏画面,你分得清这是不是现实吗?

虚幻4游戏引擎有何强大之处?

第一代虚幻游戏引擎(英文名是Unreal Engine,简写UE)在1998年由Epic Games公司发行。当时Epic Games公司为了适应游戏编程的特殊性需要而专门为虚幻系列游戏引擎创建了一种名为UnrealScript的编程语言,该语言让这个游戏引擎变得非常容易方便,因而这个游戏引擎开始名声大振。

接着,2002年,Epic发布了下一代游戏引擎UE2。这时候,在虚幻引擎提供的关卡编辑工具UnrealEd中,能够对物体的属性进行实时修改。它也支持了当时的次世代游戏机,像PlayStation2,XBox等。

到了2006年,Epic发布了下一代游戏引擎UE3,这可能是最受欢迎和广泛使用的游戏引擎。这时候的UE3又发布了一个极其重要的特性,那就是Kismet可视化脚本工具,Kismet工作的方式就是以用各种各样的节点来连接成一个逻辑流程图。其最牛逼的地方在于,使用Kismet你甚至不需要掌握任何编程知识。你可以借助Kismet使得不需要写一行代码来开发一个完整的游戏。 

到了2014年5月19日,Epic发布了Unreal4,目前最新也是Unreal4。这次版本换代也是有了巨大的改变,它已经完全移除了UnrealScript语言,并且用C++语言来代替它。在之前的版本,如果你想修改这个引擎来开发你自己的游戏,你必须用UnrealScript,也就意味着你要学习一门新的语言。不过现在,如果你要修改这个引擎,你可以用C++来完成。这对于绝大部分习惯于C++的游戏引擎工程师来说,使用自己热爱的C++语言来工作,绝对是一件天大的喜事啊。 

不但如此,游戏引擎的源代码已经可以从Github开源社区下载。这意味着开发者对游戏引擎有着绝对的控制权,实质上你可以修改任何任何东西,包括物理引擎、渲染和图形用户界面。 

它也提供了一些叫热更新的功能。什么叫热更新呢?通常,如果你想对游戏的代码进行一些修改,你必须要停止游戏才能进行修改,然后再次运行看看修改后游戏的效果。然而,使用热更新功能,你可以修改游戏而不需要停止或暂停游戏。任何在游戏代码的改变会即时更新,并且你可以看见它会在游戏中实时反映出来。 

UE4是跨平台的,你可以用来制作Xbox One、PlayStation4(包括索尼的Project Morpheus虚拟现实设备),Windows PC,Linux,Mac OSX,HTML5,iOS和安卓,就连虚拟现实设备Oculus Rift也支持。 

另一个重大的改变是,在2015年初,虚幻4已经可以完全免费下载和使用了,之前的版本是需要支付一定费用的。现在,你可以用来开发游戏,并且发行,而且不需要为UE4游戏引擎支付一分钱。只有在你赚到了3000美元收益之后,你才需要支付5%的技术使用费。 

另一个UE4提供的特性是商城,你可以在商城中购买和上传游戏资源。这些游戏资源可以包括动画,3D建模,材质,声音效果,预制游戏等等。这也是一个令没有游戏资源或者没有人力来开发资源的开发者振奋的消息。它们可以商场购买并直接应用于自己的游戏中。开发者也可以上传自己的工作成果到商城来赚钱。 

这个虚幻4小白系列教程,是面向于没有使用过UE4的新手,但需要一点点C++的知识(但也无需太多,一般读过任何一本C++教材都能看懂本教程)。我们从非常基础的下载安装引擎开始,到更高级的上传作品到谷歌PlayStore,都会涉及。我们会使用UE4来一步一步地制作我们的游戏,Let’s Start From it,你的游戏开发之路!

下图为UE4游戏引擎制作出来的官方示例宣传视频画面:



2017-05-17 23:06:45 qq_31828929 阅读数 7116
  • 从这里开始虚幻4-Editor介绍 v4.18

    本课程系列取名英译系列,是录制人员参考国外英文原版经典教程,结合中国人的习惯录制而成。希望能够给大家以帮助。从这里开始虚幻4系列教程,是Unreal的官方发布的入门教学,非常经典,是学习Unreal的佳入口。

    2373 人正在学习 去看看 杨石兴

首先我们将使用虚幻编辑器中的类向导生成基础 C++ 类

,以便蓝图稍后进行延展。下图展示了向导的第一步 - 新建一个 Actor。

这里写图片描述

这里写图片描述
这里根据对character、pawn和actor的描述,知道了pawn是actor类型,而charactor是pawn的一种类型。

进程中的第二步是告知向导需要生成类的命名。下图显示的第二步中使用了默认命名。

这里写图片描述

选择创建类后,向导将生成文件并打开开发环境,以便开始编辑。这便是生成的类定义。如需了解类向导的更多信息,请查阅此 链接 。
这里我们建立了一个继承与actor类的类myactor。然后可以从微软的VS里面进行编写。

这里写图片描述
就像上面的图里面的位置,可以找到我们要编写的myactor的.h和.cpp文件。

myactor.h文件:

#include "GameFramework/Actor.h"
#include "MyActor.generated.h"

UCLASS()
class AMyActor : public AActor
{
    GENERATED_BODY()

public: 
    // 设置该 actor 属性的默认值
    AMyActor();
    // 游戏开始时或生成时调用
    virtual void BeginPlay() override;

    // 每帧调用
    virtual void Tick( float DeltaSeconds ) override;
};

这里的BeginPlay()和Tick( float DeltaSeconds )都是声明的为虚函数。

BeginPlay() 是一个事件,将告知您 Actor 已以可操作状态进入游戏中。现在便适合开始类的游戏性逻辑。Tick() 每帧调用一次,对应的时间量为自上次调用传入的实际运算时间。在此可创建反复逻辑。如不需要此功能,最好将其移除,以节约少量性能开销。如要移除此功能,必须将构建函数中说明 tick 应该发生的代码行删除。以下构建函数包含讨论中的代码行。

而在构造函数里需要声明actor 设为每帧调用就得用下面的写法:

AMyActor::AMyActor()
{

    // 将此 actor 设为每帧调用 Tick()。不需要时可将此关闭,以提高性能。

    PrimaryActorTick.bCanEverTick = true;

}

构造函数是你在调用这个类时就会默认去调用的,比如你用这个类建立一个对象,然后就会自动调用构造函数去进行初始化。

下面是介绍把属性出现在虚幻编辑器中,这就要用到宏定义

现在即可创建一些属性(设计师可在虚幻编辑器中设置这些属性)。使用特殊宏 UPROPERTY() 即可轻松将属性公开到虚幻编辑器。只需在属性声明之前使用 UPROPERTY(EditAnywhere) 宏即可,如以下类所示。

UCLASS()
class AMyActor : public AActor
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere)//可以在任何地方编辑。
    int32 TotalDamage;

    ...
};

执行这些操作后,即可在编辑器中对数值进行编辑。有多种方式控制其编辑方法和位置。为 UPROPERTY() 宏传入更多信息可完成此操作。例如:如需 TotalDamage 属性和相关属性出现在一个部分中,可使用分类功能。以下属性声明对此进行演示。

UPROPERTY(EditAnywhere, Category=”Damage”)
int32 TotalDamage;
用户需要编辑此属性时,它将和其他属性(这些属性已以此类型命名标记)一同出现在 Damage 标题之下。这可将常用设置放置在一起,便于设计师进行编辑。

现在让我们将相同属性对蓝图公开。

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=”Damage”)
int32 TotalDamage;
如您所见,存在一个蓝图特有的参数。正是此参数使属性为可读取和可编写状态。还存在一个单独选项 - BlueprintReadOnly。可通过此选项使属性在蓝图中被识别为常量。此外还有多个选项可控制属性对引擎公开的方式。

继续讨论以下部分之前,我们来添加一些属性到这个示例类。已有属性对此 actor 输出的伤害总量进行控制。我们更进一步,实现随时间输出伤害。以下代码添加了一个设计师可进行设置的属性,和另一个设计师可查看但无法进行更改的属性。

UCLASS()
class AMyActor : public AActor
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Damage")
    int32 TotalDamage;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Damage")
    float DamageTimeInSeconds;

    UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Transient, Category="Damage")
    float DamagePerSecond;

    ...
};

DamageTimeInSeconds 是设计师可进行修改的属性。DamagePerSecond 属性是使用设计师设置的计算值(详见下一部分)。VisibleAnywhere 标记意味着属性在虚幻编辑器中为可见状态,但不可进行编辑。Transient 标记意味着无法从硬盘对其进行保存或加载;它应该为一个派生的非持久值。下图将属性显示为类默认的部分。
这里写图片描述

在构建函数中设置默认值

在构建函数中设置属性默认值和典型 C++ 类方法一致。以下是在构建函数中设置默认值的两个例子,它们在功能上相同。

AMyActor::AMyActor()
{
    TotalDamage = 200;
    DamageTimeInSeconds = 1.f;
}

AMyActor::AMyActor() :
    TotalDamage(200),
    DamageTimeInSeconds(1.f)
{
}

下图是在构建函数中添加默认值后的属性视图。
这里写图片描述

为支持设计师对每个实例设置属性,数值也从给定对象的实例数据中加载。此数据应用在构建函数之后。与 PostInitProperties() 调用链挂钩即可基于设计师设置的数值创建默认值。此处的进程范例中,TotalDamage 和 DamageTimeInSeconds 为设计师指定的数值。即时这些数值为设计师指定,您仍然可以为它们提供恰当的默认值,正如我们在上例中执行的操作。

如未向属性提供默认值,引擎将自动把属性设为零(指针类设为 nullptr)。

void AMyActor::PostInitProperties()
{
    Super::PostInitProperties();
    DamagePerSecond = TotalDamage / DamageTimeInSeconds;
}

下图是添加以上 PostInitProperties() 代码后的属性视图。
这里写图片描述

2018-06-02 21:51:36 zhengliuguo 阅读数 2124
  • 从这里开始虚幻4-Editor介绍 v4.18

    本课程系列取名英译系列,是录制人员参考国外英文原版经典教程,结合中国人的习惯录制而成。希望能够给大家以帮助。从这里开始虚幻4系列教程,是Unreal的官方发布的入门教学,非常经典,是学习Unreal的佳入口。

    2373 人正在学习 去看看 杨石兴
摘要: 一位程序员网友小保哥分享自己的UE4快速上手过程,只是笔记,52VR做了一点更加适合阅读的修改,整理给大家。

  1. 首先,本文只是针对有比较熟练C++技能的程序员,他可以没有任何图形学或游戏引擎方面的经验知识。
  2. 其次,本文只是偏重工程方面的介绍,没多少理论知识的介绍,目的纯粹就是让一个完全没有接触过UE4的C++程序员能够很快着手开发UE程序。
  3. 再次,本文只是个人的经验之谈,甚至有可能有理解错误的地方,因为我也只是学了UE4一个多月,但是确实能够让我很短时间就能从事UE4的开发了。
  4. 最后,源于以上几点,高手勿喷,如有不爽,绕行即可。若有闲情雅致,可以顺手指点指点,不吝感激。

我研究的是UE4.10,因为电脑上只下载了这个,看的官方文档是4.9的。

以下就按时间顺序排列我的学习过程:

1)创建工程

对程序员来说,甭管这个引擎如何如何,我如果用它开发一个什么东西,首先得创建一个工程,然后把所有相关的代码都写到这个工程里。这就是我们要知道的第一步。那么在UE4里如何创建一个工程呢?在启动引擎程序时,自己会蹦出一个窗口,让你选择打开电脑上已有的工程或者创建新的工程。UE4工程只有两种类型:蓝图的、C++的。这两种类型的工程其实没有任何实质性的区别。把UE4工程分成这两种类型,表现出来的唯一区别是:C++类型的工程创建的时候,会自动弹出visual studio来打开这个UE4工程。仅此而已。

而对程序员来说,蓝图类型的工程创建好后,在该工程的UEditor的File菜单里会有一项[Create Visual studio Project],中文版是[生成Visual Studio项目],以后我只针对英文版来写了。点击一下这个菜单项,对应的Visual Studio工程文件就创建好了。相应的,File菜单里还有[Open Visual Studio]菜单项,作用就是在Visual Studio里打开该工程对应的代码文件。其他菜单项暂且放下,一会儿再回头说几句就懂了。

2)UE4的工程配置

甭管是蓝图类型还是C++类型的,工程反正是创建好了。

到这里,我们先不管如何往这个工程里写代码添加新功能。我们直接Build一下这个工程:UEditor界面工具栏上的Build按钮或者VisualStudio的Build按钮。没有任何悬念,结果肯定是Build成功。

哦,说到这里,提一下,UE4.10以上必须安装Visual Studio 2015。我们打开对应的Visual Studio工程(如果是蓝图类型,按照上面所述方法生成Visual Studio工程即可)。

215337owpzs0wsovpwpqpp

在VisualStudio里,我们能看到这个工程里的代码文件就很少的几个,如图,这张图片里VirtualCamera是我的工程名。注意看.Target.cs后缀的文件,这里所谓的Target就是Makefile文件里的Target的意思。我们知道手写Makefile文件在某些情况下是比较费劲的行为,因此程序员们造出了很多Automake工具用来自动生成Makefile文件。因此,UE4自己也造了一个Automake工具,用来生成Makefile文件。这个Automake工具是C#写的,用C#文件来描述Make的规则,比如这个Target.cs就是用来描述Makefile里最终的成品,可以有多个Target.cs,但它们不一定同时起作用。比如vs编译类型选为[Development]而不是[Development Editor]时,那个Editor.Target.cs文件描述的Target的Make规则就不会起作用,此时,即便你从硬盘上和vs里删掉这个.Editor.Target.cs文件,工程也能成功编译并运行。文件列表里还有类似.Build.cs文件,这个就描述类似Makefile里的中间目标文件的Make规则。这些cs文件是在添加蓝图类或者c++代码时自动生成的,不用鸟它们,只需要知道这些cs文件是UE4的Automake工具需要的就行了,只要有了这些cs文件,我们的UE4工程就能正确编译运行。我这句话里蕴含的意思还有:对于UE4工程的编译,完全不依赖visual studio的project文件,即.vcxproj等文件。也就是说UE4使用自己的AutomationTool来读取cs文件描述的Make规则来进行编译。然而,凡是用visual studio打开的工程,必然需要一个.vcxproj文件,结合刚才讲的,我们就能明确这里visual studio的作用仅仅是方便我们阅读和编写源代码,这里visual studio的方便性还是很巨大的,不是吗!因为vs为阅读编写源代码提供了强大的支持。上一节的最后我没讲UEditor的File菜单里还有一项[Refresh Visual Studio Project],这个选项的作用就是遍历我们的UE4工程目录结构,根据遍历的结果,刷新.vcxproj文件,然后让vs重新加载这个更新的proj文件,这样只要我们往工程目录里增加或删除了代码文件,只需点击一下这个菜单项,在vs里就能反映出这种变化。


3) UnrealAutomationTool

工程的Build是一个很长的过程,里面分成多个阶段,我只关心里面最重要的阶段,就是代码文件的Compile过程。这里先介绍几个名词:UBT(Unreal Build Tool)又叫UnrealAutomationTool,这个工具主要作用就是组织Build流程,直白点说就是按一定顺序调用不同的工具完成整个Build过程。首先调用的肯定是解析各个cs文件的工具,解析的结果就是Build的目标,先Build谁,再Build谁。Build的顺序和目标定下来之后,就要开始真正的Build动作了,也就是Compile代码文件,Link出目标。Compile的第一步是调用UHT(UnrealHeaderTool)工具,这个工具就类似于C++里的预处理器,UHT读取.h文件,解析里面的一些元信息(UE4定义的,比如[UCLASS],[USTRUCT][BlueprintCallable],UPROPERTY,UFUNCTION等等),这些元信息不是C++语言的一部分,C++编译器自然无法识别,所以需要UHT工具先解析这些元信息,生成对应的.generated.h文件,在这个.generated.h文件里的内容就是用合法C++代码模拟的刚才那些元信息。然后原先.h文件里的所有元信息文本都会被删除。这一步完成后,出来的就都是合法的C++的代码文件了,可以直接送给C++预处理器处理,进而编译器,链接器。最终产出Build的目标,完成Build过程。参考一下下图:

(点击图片看大图)

215337bawz3ltwachrvvlh215337jtlvozvoxztplvws

4)还是要说说Blueprint

到这里,对于C++程序员来说,算是掌握了总体的开发流程,知道如何开始,如何结束了。

那么剩下的就是学习如何往工程里添加代码,并学习代码怎么写--学习有哪些api可以用,如何用。这是UE4开发里最重要的一块了,废话,前面说的都只能算是常识,不能算UE4开发。然而只有知道了这些常识之后,我们接下来才可以真正开始学习开发。

首先开宗明义,学习UE4最快速的捷径就是Blueprint,这是我学了1个多月的UE4的最大感触。

在UE4的官方文档里,讲Blueprint时首先就说到:在UE4里,Blueprint支持的功能涵盖了C++支持的几乎所有特性,即BP(Blueprint简写)几乎等价于C++。然而,话锋一转,其又说到,BP有其适用场合,不是所有场合都适合用BP,因为某些场合BP的性能比原生C++代码要慢。

适合用BP的场合:主要就是对性能要求不是特别高的应用场景,比如绝大部分Event的响应等等。然而在我看来,大部分的开发任务不就是Event的响应么,这也就是说BP适用UE4开发的绝大部分场景。而且,众人所说BP太慢,纯粹是无理由的偏见,我承认某些BP可能没有原生手写C++代码快,但并不代表BP性能低。

从开发效率上来看,能用BP的地方尽量用BP所带来的好处实在是不用多说了。尤其对新手来讲,写C++代码都不知道有哪些东西可以调用,更别谈写高效的C++代码了。因此,对新手来说,学习BP是必须的。其最重要的作用,就是让UE4新手能快速的掌握引擎在代码层面提供的功能。

然而,在认识到这一点之后,我并没有立即开始BP的学习,而是先学习了一下如何让C++代码与BP交互,具体的知识少不了要自己去看官方文档,我这里只是列出我的经验。

还要提一下:凡是能放到unreal场景里的东西都是Actor对象,对应C++里的AActor类型。Actor只是一个壳,它提供的所有功能都是由它包含的Component来提供的,不同的Component能提供不同的功能,最后表现出来的就是Actor具有所有这些Component提供的功能。Component的总分类,见链接,这个和Unity中的组件有些类似。我能保证这里的文档真正看懂的话,C++编程的部分从动手方面来讲不存在任何问题了。接下来看BP文档那一章,掌握BP也没有任何悬念,而且是很快乐的过程,不会有任何难度。

215337nduj0u6qotdn6on6

#5)GamePlay

关于游戏模式,这里的文档也需要在看BP前提前阅读一遍 :

215337fee8jelj5xjlj78b

这里也有一张脑图,大家看看:

(点击图片看大图)

220522vfvwvt94ukm7vmvl

UE4 的 C++ 开发体验

阅读数 1801

没有更多推荐了,返回首页