使用虚幻引擎中的C++导论(二-UE4基类)
使用虚幻引擎中的C++导论(二)
第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢。
第二,某些细节操作,这篇文章省略了,如果有不懂的,去看其他教程。
第三,没有C++编程经验,但有其他OOP语言经验的朋友。要先了解C++的基础。
深入研究
你依然和我在这里冒险。太好啦,下一个话题,围绕游戏类的继承关系进行介绍。在这个部分,我们将要看到很多基类,谈一谈他们之间的关系,在这里我们可以看到虚幻引擎如何使用继承和组合去建立自己的游戏特性。
游戏类:Objects, Actors, and Components(对象,物体,组件)
你可以从很多的游戏基类中派生出这4种主要的类,它们是UObject,AActor, UActorComponent,和 UStruct。他们的每一块都建立自下面的部分。当然了,你可以建立一个不继承任何类的类,但它们将不能用于引擎特性有关的部分。典型类(普遍意义上的C++类)的使用方法是,在UObject对象层次之外创建的:集成第三方库;操作系统的特定功能包装,等等。
虚幻对象(UObject)
在虚幻中最原始的基类叫UObject。这个类,加上UClass类,提供了若干虚幻引擎的主要基础服务:
- 属性与方法的反射
- 属性信息序列化
- 垃圾回收
- 通过名称查找虚幻对象
- 为属性配置值
- 属性和方法的网络支持
每个派生自UObject的类都有一个单独的UClass类被创建,它包含所有有关类实例的元数据。UObject和UClass是每一个虚幻对象的最高父类。理解他们之间的区别的最好办法是,UClass将描述UObject看起来是什么样子的,如什么属性是可以被序列化的,什么属性可以支持网络,等等。很多游戏开发不会直接继承UObjects类,但是作为替代,那些类继承AActor类和UActorComponent类。在写游戏代码时,你不需要知道UClass/UObject类是怎么工作的细节,但你最好知道这些类在这个系统中是存在的。
AActor
AActor类意味着它将是游戏体验的一部分。AActor类可以被设计师在关卡设计中放置,也可以通过运行时由系统放置。所有的对象都可以通过继承该类,让对象可以放置在关卡中。比如说,AStaticMeshActor类,ACameraActor类,APointLight类。AActor类继承UObject类,这样就得到了前一节(翻译的上一篇文章)的所有特性。AActor可以明确的被销毁,可以通过C++代码或蓝图操作,或在某个拥有的关卡(场景)不再被装载时,通过标准垃圾回收机制销毁。AActors 负责游戏对象的高级行为。AActors 同样是可以再网络中复制的,在网络复制时,AActors 可以同时分发信息到支持网络的UActorComponents (组件)中。
AActors 有他们自己的行为(通过特殊继承),但他们也像UActorComponents 层次关系的箱子一样(通过特殊组合),这是通过AActors 的RootComponent (根组件)成员完成的,它包含了一个单独的UActorComponent ,反过来说,可以包含很多其他组件。在把AActor 放置到关卡之前,AActor 必须包含最少一个USceneComponent类的组件,USceneComponent类可以对AActor 进行平移,旋转,缩放。
(通俗解释:一定要让整个物体至少有个形状的组件,才能放到场景中)
AActors 有几个事件会在AActors 的生命周期中被调用(触发)。下面的列表简单列出了一些事件说明。
- BeginPlay - 当物体第一次进入场景时触发。
- Tick - 每一帧调用一次。
- EndPlay - 在物体离开游戏空间时触发。
查看更多关于AActor类的详细说明,传送门
运行时生命周期
现在将要介绍的是,我们刚才提到的生命周期,对于被放置进关卡中的AActor来说,要理解生命周期,可以简单的想象一下:物体被放进关卡,然后关卡在某个时候被关掉了,最后物体被销毁了。那么在运行时的生成和销毁的过程是什么样的呢?在运行Spawning(产卵)时,虚幻引擎会调用生成方法。Spawning是一个Actor比新建一个普通对象稍微复杂一点的“生成”。因为,为了满足Actor的所有功能需求,Actor需要在多种运行的系统进行注册。初始位置和旋转需要进行设置。物理系统需要知道Actor的存在。时钟计时需要知道物体的存在。还有很多其他系统。因此,我们有一个方法为Actor提供Spawning。UWorld::SpawnActor(),每当一个物体成功的Spawning之后,BeginPlay()方法将被调用,紧接着Tick()方法将在下一帧被调用。
当Actor生命周期结束时,你可以调用Destroy()方法。在这个过程中,EndPlay()方法将被调用,在这里你可以自定义一些逻辑。另一些控制Actor生命周期长短的选项,是使用Lifespan 成员。你可以在Actor构造或其他代码运行时,设置timespan(时间跨度)。一旦该时间过期,Actor将自动调用Destroy()方法。
想要学习更多关于 产卵 Actor ,请看生成Actor页,传送门
UActorComponent
UActorComponent有他们自己的行为,他们通常负责功能化,这些组件通常被AActor共享。比如,提供可视化网格,粒子系统,摄像机视角,物理交互。当AActor在游戏中是一个与游戏整体角色有关联的高级目标,UActorComponent通常去表现个别的任务,去支持更高级别的对象。组件同样可以连接到别的组件,或者可以作为Actor的根组件。一个组件只能连接到一个父组件或父Actor,但可以有很多子组件连接到他自己。这些组件组成了组件树。子组件的位移,旋转,缩放是相对于父组件或父Actor的。
这里有很多途径去使用Actor或组件,有一种对于Actor与组件关系的思考是这样的,Actor表示“ 这个是什么东西”,组件表示“这个东西是由什么组成的”。
- RootComponent - 树型组件组织关系中的根部
- Ticking - 组件的时钟,是Actor时钟的一部分
剖析第一人称角色
在我们上一个小结,我们说了好多解释性的信息,但没有太多演示。为了更好的说明Actor与组件之间的关系,让我们深入挖掘一个蓝图类,这个类在你新建第一人称模板项目时就已经生成了。下面的图片中展示了FirstPersonCharacter Actor的组件树。根节点是一个CapsuleComponent(胶囊组件),连接着“胶囊组件”的是,一个ArrowComponent(箭头),Mesh (网格),FirstPersonCameraComponent(摄像机)。最下面的子叶节点是Mesh1P 组件,意味着第一人称网格关联到第一人称摄像机。

事实上,这个组件树的效果如下图所示,你可以看到所有的组件在3D空间中如我们期望的一样。

在这个例子中,组件树中的组件都连接于一个Actor。你可以通过使用继承和组合,去创建复杂的对象。当你想要自定义已有的AActor或UActorComponent时,需要用继承。在很多不同的 AActor类型中共享功能时,需要用组合。
UStruct
使用UStruct,你无须继承特定的类,你只需要在结构体上标记USTRUCT()宏命令,引擎会帮你做其他基础工作。不像UObject那样,UStructs 不能被垃圾回收。如果你生成了他们的动态实例,你必须自己管理他们的生命周期。UStruct是一种朴素而古老的数据类型,它有UObject 的反射机制支持,但是没有虚幻引擎编辑器,蓝图操作,序列化,网络,等等,这些支持。
直到现在,我们谈了谈类的构造和基础继承。是时候再一次选择你的路了。你可以去阅读我们的游戏类,传送门。通过看实例去了解更多信息。或者为了制作游戏挖掘更深的C++特性。
使用虚幻引擎中的C++导论(二-UE4基类)的更多相关文章
- 使用虚幻引擎中的C++导论(四-内存管理与垃圾回收)(终)
使用虚幻引擎中的C++导论(四)(终) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如 ...
- 使用虚幻引擎中的C++导论(三-反射系统与迭代器)
使用虚幻引擎中的C++导论(三) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如果有不 ...
- 使用虚幻引擎中的C++导论(一-生成C++类)
使用虚幻引擎中的C++导论(一) 第一,这篇是我翻译的虚幻4官网的新手编程教程,原文传送门,有的翻译不太好,但大体意思差不多,请支持我O(∩_∩)O谢谢. 第二,某些细节操作,这篇文章省略了,如果有不 ...
- 虚幻引擎中的数组---TArray: Arrays
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接: http://blog.csdn.net/cartzhang/article/details/45367171 作者:ca ...
- 图像处理中创建CDib类时无法选择基类类型时怎么办
图像处理中创建CDib类时无法选择基类类型时怎么办? 类的类型选择Generic Class 在下面的篮筐里输入CObject就行了
- QIODevice (Qt中所有 I/O devices 的基类,QFile,QBuffer,QTcpSocket等)
QIODevice是所有Qt I/O设备的基类,它提供了对支持块读写设备(例如QFile,QBuffer,QTcpSocket)的通用实现和抽象接口.QIODevice是一种抽象,不能被实例化,但是, ...
- [原][unreal][UE][spark]分析unreal engine 虚幻引擎的粒子编辑器:Cascade
参考:https://www.raywenderlich.com/270-unreal-engine-4-particle-systems-tutorial (使用了一个飞机射击游戏的粒子来展示,全英 ...
- C#在派生类中调用基类成员
一.在派生类中调用基类成员 在C#的派生类中,我们可以使用base关键字调用基类中的公有或者受保护成员.这些成员只能是构造函数.实例方法或者实例属性. base关键字调用基类成员的语法格式如下: ba ...
- (转) C++中基类和派生类之间的同名函数的重载问题
下面有关派生类与基类中存在同名函数 fn: class A { public: void fn() {} void fn(int a) {} }; class B : public A { publi ...
随机推荐
- C#中的var类型
var关键字是C#3.0开始新增的特性,称为推断类型(其实也就是弱化类型的定义) . VAR可代替任何类型,编译器会根据上下文来判断你到底是想用什么类型,类似 OBJECT,但是效率比OBJECT高点 ...
- IOS 在控制器间跳转实现过渡动画
已经掌握了CALayer下的CATransition动画在同一个控制器下实现,但是在不同控制器间跳转又该如何实现呢? MyViewController *myVC = [[MyViewControll ...
- crontab不能正确执行的问题
近期在部署crontab任务的时候,总是遇到在shell中单独执行正常,但是放到crontab定时执行出错的问题.若出现这类场景,九成就是环境变量的问题. 因为我的定制任务,基本上都需要使用sqlpl ...
- sql CONCAT字符串连接函数
有的时候,我们有需要将由不同栏位获得的资料串连在一起.每一种资料库都有提供方法来达到这个目的: MySQL: CONCAT() Oracle: CONCAT(), || SQL Server: + C ...
- LintCode Search For a Range (Binary Search)
Binary Search模板: mid 和 target 指针比较,left/ right 和 target 比较. 循环终止条件: 最后剩两数比较(while(left + 1 < righ ...
- html5本地存储的解决
1.解决了Cookie 4K存储大小的问题2.解决了请求头常带存储信息的问题3.解决了关系型存储的问题4.跨域问题,跨浏览器*在 HTML5 中,数据不是由每个服务器请求传递的,而是只有在请求时使用 ...
- C#中动态读写App.config配置文件
转自:http://blog.csdn.net/taoyinzhou/article/details/1906996 app.config 修改后,如果使用cofnigurationManager立即 ...
- Python学习笔记——文件操作
python中,一切皆对象. 一.文件操作流程 (1)打开文件,得到一个文件句柄(对象),赋给一个对象: (2)通过文件句柄对文件进行操作: (3)关闭文件. 文件对象f通过open()函数来创建 ...
- Redis客户端之Spring整合Jedis,ShardedJedisPool集群配置
Jedis设计 Jedis作为推荐的java语言redis客户端,其抽象封装为三部分: 对象池设计:Pool,JedisPool,GenericObjectPool,BasePoolableObjec ...
- Storm简介
Storm特性 1. 低延迟和高性能 在一个小集群中,每个节点每秒可以处理数以百万计的消息. 2. 可扩展 在Storm集群中主要有三个实体:工作进程.线程和任务.Storm集群中每台机器上都可以运行 ...