失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > UE4 GamePlay架构

UE4 GamePlay架构

时间:2022-09-13 06:01:06

相关推荐

UE4 GamePlay架构

UE4 GamePlay架构

前言GamePlay架构_1_Actor和ComponentGamePlay架构_2_Level和WorldGamePlay架构_3_GameInstanceGamePlay架构_4_PawnGamePlay架构_5_Controller StateGamePlay架构_6_GameMode和GameStateGamePlay架构_7_总结

前言

关于这篇文章,是在读了UE4深入浅出后自己根据对ue4 gameplay 的架构理解所整理的。本人非大神,只是ue4的初学者。文章中定会有不少理解错误的地方。希望大家指正。

GamePlay架构_1_Actor和Component

UE 是一个面向对象的引擎。UE的架构和大多数的面向对象的架构一样。

举个例子

java的基类为Object。UE的基类为UObject。

同样,UObject提供了最底层的支持:元数据,GC垃圾回收,序列化,Class Default Object等。

而,如果只是单单使用蓝图进行变成的话,我们只需要知道这么一个概念就行。

如果说要列举UE世界中的“主要成员”,Actor与Component绝对是当仁不让。

继承了UObject的Actor,实现了自身的特殊方法, Replication(网络复制),Spawn(生成),destroy(销毁),Tick。

而Component则是作为部件的形式存在。它通常是添加到Actor中使用。

其实,Actor实际上只是以一个概念的形式存在,它通过添加到自身的Components在UE世界中应用。包括它的位置信息和展示方式(比如说外形)。

我们则可以通过Actor得到component的信息。比如位置信息

实际上底层也是通过转换到获取rootComponent 的transform来返回的

/** Returns location of the RootComponent* this is a template for no other reason than to delay compilation until USceneComponent is defined*/template<class T>static FORCEINLINE FVector GetActorLocation(const T*RootComponent){return(RootComponent!=nullptr)?RootComponent->GetComponentLocation():FVector(0.f,0.f,0.f);}

所以,Actor在实际中只实现了一些基本的“生存能力”。比如说添加删除Component的能力,事件调度能力,心跳能力(tick),其余的能力都是通过添加一个个实现了特殊功能的Component进而增加自己的buff。

而,Actor与Actor之间, Actor与Component之间也可以进行嵌套组合,最常用的嵌套组合应用就是,attach之后可以带动attach对象进行transform的改变,就像是汽车后拖着另外一辆汽车,可以通过前车的动作,带动后车改变。

GamePlay架构_2_Level和World

什么是world,什么是level?

在ue中,world可以看作是我们的地球,它其实是一个大容器,可以包裹大陆(level)。

由于world的特性,我们可以在world中设定一个统一的信息(info)。比如说光照信息,比如说物理属性。只要你在这个世界中,你就必须要遵循这些基本规则。

从源码可以看出,level也是属于UObejct的子类,那是否和其他的子类一样支持蓝图编辑呢?答案是肯定的。我们有一种东西叫做“关卡蓝图”。

什么是关卡?其实更细致的答案应该是Actor的一个容器,也可以说它是actor管理器。所以,在容器里,我是可以取到任意Actor的。既然我是容器,我提供了空间存放actors,我就有能力对这些actors进行调度使用。

在关卡蓝图中,我们可以通过先选中关卡中的actor,然后到关卡蓝图中右击创建一个该actor的引用,进而可以对这个actor进行所有可对actor进行的操作。

其实,一level一world,一关一世界。有一种东西叫做世外桃源。我们在加载关卡的时候可以通过一个命令进行开启新世界。进而可以开启新的历程。

当然,话是人说的。我们还有一种说法叫地球村。世界上所有的大陆都归结于这个世界上。这就是ue里面讲的关卡流。通过关卡流,我们可以构建庞大的开放世界。

我们可以整合所有需要的levels到主level中。

然后通过一下两个节点进行加载卸载。

具体内容参考官网:/latest/CHN/Engine/LevelStreaming/index.html

话又说回来。我们之前说过,每个level都可以设置自己独有的特性,比如上面说的物理属性和后续会说的controller,gamemode等,在通过关卡流加载之后到底是以那个level的为主了?

一关一世界毫无疑问是当前关卡,因为他就是世界的主体,关卡流的话歧视就是主关卡,也就是

这样制定规则其实也是可以理解的,不能在大家都设置的规则上,即公共规则如物理属性,进行叠加,这样整个世界就乱套了。所以,做人讲究入乡随俗。但是,在非公共规则上则是可以特殊设置。

GamePlay架构_3_GameInstance

什么是GameInstance?通俗的讲,就是凌驾于world之上的更高级的类。

在程序运行开始至结束之间都会存在的一个对象。

那么它的作用是什么呢?

一般来讲它有以下几个作用:

编写跳转逻辑,一般来说我们可以把Level的跳转写入gameinstance中它在游戏运行过程中始终存在,所以可以存储在游戏运行过程中需要用到的变量(注:如果是持久化数据,建议用savegame直接保存在本地)

GamePlay架构_4_Pawn

通过源码我们可以发现,pawn 是继承与 actor 的。也就是说,他是actor.

actor 有很多的子类。有些是静态的staticmeshactor,有些是 cameraactor ,有些可以被控制做出反应,如ai控制的npc和玩家控制的游戏人物。所以,ue就在引擎中进行划分,而pawn刚好是划分到可被控制的这个类别中。

这下我们可以清楚的了解pawn的作用了。他是用于和玩家互动的,不管是接收玩家的输入做出相应动作(游戏人物)还是根据玩家的输入作出反应(ai)。

这样,我们就可以知道,pawn其实就是 走卒的意思。很形象,也很贴合ue对于pawn的定义。

而pawn,也是有几个子类的。

由此可以看出,pawn是actor的子类,而pawn的子类有 character,defaultpawn

EQSTestingPawn是character子类,官方文档中有对他介绍

场景查询系统测试 Pawn(EQSTestingPawn)是一个特殊的 Pawn 类,可对场景查询实际进行的操作进行查看。场景查询的实际组成将定义所创建内容的尺寸和形状,但始终以彩色球体显示。球体的色阶从绿色到红色,表示场景查询执行的诸多测试的匹配度。蓝色球体表示失败或布尔型测试返回 false(如 Trace 测试)。

SpectatorPawn是观察者pawn,也就是观众。在官方文档中是有进行介绍

The SpectatorPawn class is a subclass of DefaultPawn. Through a GameMode, different classes can be specified as defaults for Pawn and SpectatorPawn, and this class provides a simple framework ideal for spectating functionality. Like DefaultPawn, it has a spherical CollisionComponent, although the StaticMeshComponent is not created due to the implementation of .DoNotCreateDefaultSubobject(Super::MeshComponentName). The movement for the SpectatorPawn class is handled in the SpectatorPawnMovementComponent; the no-gravity flying behavior is the same as in the DefaultPawnMovementComponent, with added code for handling or ignoring time dilation as necessary.

对于在日常开发中,涉及到的较多是Character和DefaultPawn

如果是开发人物,一般创建的是Character,他是ue为我们开发人员打开一个方便之门,添加了大多数由pawn创建人物必须添加的一些组件。

同理 DefaultPawn 也是一样的,在pawn的基础上添加了一些作为玩家交互对象所必要的一些组件和一些设置。

如果你想要最大自由化,可以通过创建以pawn为父类的类来进行编辑。若想要让pawn变成玩家控制的人物对象,只需要添加人物对象所必要的组件,比如人物模型和ik特性。

GamePlay架构_5_Controller State

来张图

遥想以前接触过的java,做项目时讲究模式,mvc更是天天不离口。

对于一个程序来说,好的设计模式带来的不仅仅是思路更清晰,他也带来了无上的可扩展性和可维护性。而ue在设计引擎就为广大用户考虑这个问题了。

controller 和gamemode就是ue为广大用户所准备的设计模式所抽象出来的类。

controller的作用是为角色编写逻辑,理论上controller与player的对应关系是一对一的关系。在ue的初心中,他由衷希望我们在player,也就是pawn中编写的是动作和检测,调用动作的方法写于controller中。这样就相当于把动作和逻辑区分开来。

而controller则有两个子类,一个是AIController,一个是PlayerController。

顾名思义,AIController编写的是ai的控制逻辑。但是,其实,在ai逻辑方面我们也尽量不要自己硬编码去写ai逻辑,在ai的控制逻辑上,ue又为我们提供了一套可行方案,就是行为树。

而playercontroller则是针对player所使用的控制器,我们在里面响应玩家的输入,来处理逻辑,来实现pawn的创建和销毁,控制玩家的生杀大权,也可以随时切换所要控制的pawn,达到切换角色的效果。而,在游戏中,controller才是能真正代表玩家的东西,pawn只是一个展示形式,他可以长这样,拥有这样的能力,也可以长那样,拥有那样的能力。而controller只管我如何操控。

再来张图

info存储的是信息,游戏中的一些个数据。而playerstate,和gamestatebass作为他的子类,功能也是存储信息,只是这个信息是细分下的类别。主要存储的是游戏的状态信息。

再顾名思义,playerstate存储的是玩家的游戏状态,这里不是存储playercontroller的游戏状态,而是对应玩家pawn,也就是ue推荐的character的游戏状态。

state的特性是,他是网络复制属性的。他的更改时时同步到网络中所有客户端。但是,当pawn销毁的时候,他也会随他而去。

GamePlay架构_6_GameMode和GameState

首先来谈谈gamemode

什么是gamemode?笼统来讲,gamemode是一个游戏世界的mode,规则,逻辑。

如图所示,打开每一个level ,都有一个worldsettings,在这个设置里,可以设置该level所使用的gamemode。配套的,每个gamemode是有对应defalultpawn,controller,gamestate,playerstate等。

按照样来看,是否就是说一个level配套一个gamemode呢?甚至配套其余对应的几个设置呢?是,也不是……

是,道理就是,像我们之前说的,一关一世界,一level一world。每个level在没有组合其他level的时候就是自己一个世界。

不是,就是像刚才说的,level如果组合了其他子levels,比如说用关卡流。这样,每个world就是这么多level组合而成。

那么,我们通常用gamemode做什么操作呢,它起到的作用是什么呢?

通常,我们在gamemode里面编写的是在这个世界中,或者在这“一关”中游戏的玩法,游戏逻辑。这些玩法逻辑是脱离level实体actor的,主要是这个“world”的运行规则。他不去在乎整个关卡内部如何运作,如何实际操作。

关卡内的运作,实际操作,其实就是关卡蓝图和关卡内actor所关心的东西。gamemode是一个管理者,负责调度这个“world”的运行,就像一个公司部门领导一样,他管的是整个部门,这个部门其实就是一个level,有时候一个公司就一个部门。这个部门就是这个公司的整个世界,他是不回去管理地下每个员工的动作,他只出规则,下面的员工遵守罢了。

那么什么是gamestate呢?

看到这个名称,是否感觉与之前讲到的playerstate有相似呢?

确实如此,gamestate和playerstate在理论上是一样的,他管理的是相对应等级上的一个state 信息。gamestate是gamemode的同等级信息同步与管理。与state的特性一样,他是网络复制属性的,自动同步存储在gamestate上的信息到各个端。

GamePlay架构_7_总结

如果觉得《UE4 GamePlay架构》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。