《GAMES104-现代游戏引擎:从入门到实践》-03 学习笔记
目录
一个游戏世界由什么构成
如何描述一个Game Object
如何使游戏世界动起来
游戏世界中的Events
如何管理GO
*Tick的时序问题
一个游戏世界由什么构成
一个游戏世界我们首先关注到的就是一系列可移动可操作的动态物(Dynamic Game Objects),如坦克、火炮等;还有一系列静态物(Static Game Object),如石头、棚屋等,这些静态物虽然不能交互,却是GamePlay中很关键的元素;最容易被忽略却又无处不在的是游戏的环境(Environments),它一般由天空(Sky)、植被(Vegetation)和地形(Terrain)组成;游戏中还存在着大量其他物体,如触发检测体(Trigger Area)、导航网格(Navigation Mesh)等。以上的各种对象,无论静态还是动态,我们统称为Game Object(GO)。
![](/assets/blank.gif)
如何描述一个Game Object
游戏中描述一个物体,可以分为属性(Property)和行为(Behaviour)两方面,这就和面向对象的语言相匹配了。我们可以为物体设计定义一个类,根据它的属性定义成员变量(如position、battery),根据它的行为定义成员函数(如move、scout)。
![](/assets/blank.gif)
根据上述定义描述出一个类对象后,我们还可以通过定义继承(Inheritance)类,衍生出更多的类对象,比如说一个物体在继承无人机类后,再定义弹药量属性和攻击行为,我们便得到了察打一体无人机类。
![](/assets/blank.gif)
但是继承类的使用又给我们带来了新的问题:类似水陆两栖坦克的类是继承自坦克类还是航船类?这就需要考虑将对象组件化,通过Component的组合来设计定义GO。以C语言为例,我们只需定义一个ComponentBase基类,由此派生出其他行为接口类(如Transform、Model、Motor、AI等),再根据需要实现改造这些接口类。像这样以组件的形式代替继承类的使用可以使我们对GO的设计更加灵活。
![](/assets/blank.gif)
我们要注意到Unreal和Unity中的Object和上述Game Object还是有差别的。
如何使游戏世界动起来
这就需要用到之前提过的Tick函数,在每个Tick内都让世界向前走一小步,这样世界就动起来了。
- Object-based Tick:在每个Tick内,将每个GO的每个Component的Tick函数都调用一次。
- Component-based Tick:各个Component依次调用Tick函数,比如先将Motor组件中的任务执行完,然后执行Controller组件中的任务,再执行Animation中的任务。这样流水线般的处理方式效率更高,在现代游戏引擎中也更常用。
游戏世界中的Events
以一个坦克发射炮弹为例,早期的设计方式是定义一个炮弹对象,在其爆炸时检查周围GO的类型,并对应的造成影响。
现在可以通过事件机制来解耦(Decouple)GO之间的通信,通过向不同GO发送事件,将事件交由对应的GO处理,使得不同GO之间的逻辑解耦合,降低代码的复杂性。比如当一个炸弹接触到地面时,它向周围的GO发送一个Explode事件,像Health组件监听到这个事件后,它会对应处理事件造成一个如Damage的影响。
如何管理GO
每个GO都有一个唯一标识UID和一个位置,通过这两个元素我们可以对场景中的GO进行管理。当我们对于场景中的位置没有进行划分时,一个事件的发送可能需要遍历场景一定范围内的所有GO,这样处理的时间复杂度是极高的。
我们可以将场景分为数个网格,每个网格分别管理,当发送事件时,优先对邻近的网格发送。但是当每个网格中GO分布不均时,这样处理效率又会变得很低。
![](/assets/blank.gif)
为了提高效率,我们可以对每一个网格进一步细分,每一个网格划分为更小的四个网格,构成四叉树结构,当我们需要搜查一个GO邻近的GO时,只需要在它的父节点、兄弟节点、邻近节点之间搜查即可。
还有许多其他的场景管理结构
![](/assets/blank.gif)
*Tick的时序问题
如下图中GO之间一般会出现绑定的现象,那么在执行Tick函数时,绑定的双方哪一方先执行Tick函数呢?这就要考虑Tick的时序。一般会要求父节点先执行Tick函数,绑定其上的GO随后执行。因为不同Component的Tick函数是分散到不同CPU上并行处理的,所以不同Component的Tick时序问题则会更复杂。当两个Component互相发送事件时,因Tick函数是多线程执行的,我们没有办法确定哪一方先发送,但对于多个CPU来说Tick的时序很重要,这时我就们需要一个中介的事件发送器来转发事件,并确定Tick的时序。
![](/assets/blank.gif)
总结:
- 在游戏世界中一切事物都是GO
- 每个GO都可以由Component的组合的形式来描述
- 游戏世界是通过Tick函数的循环调用一点一点动起来的
- 每个GO通过事件机制与其他GO交互
- GO的管理需要采用高效的场景管理机制
以上即是我在第三课中的收获~
课程传送门:03.如何构建游戏世界 | GAMES104-现代游戏引擎:从入门到实践_哔哩哔哩_bilibili
《GAMES104-现代游戏引擎:从入门到实践》-03 学习笔记相关推荐
- 《R语言入门与实践》学习笔记四
第四天任务: 完成项目玩扑克牌后1/2,并通过项目学会以下技能: 1)从一个数据集中抽取个别数据值. 2)在一个数据集中改变个别数据的取值. 3)编写逻辑测试程序. 4)使用R的缺失值符号NA. -- ...
- python从入门到实践学习笔记_Python编程从入门到实践:学习笔记1(第二章)
开通博客我用的理由是:读书学习时记笔记,一方面为了回顾,一方面为了督促自己.fighting! 学习Python,我买了Python编程从入门到实践. 我将从第二章开始记录我认为我以后会忘记以及重要的 ...
- 《R语言入门与实践》学习笔记二(chapter4~6)
目标 : 如何存储.检索和修改计算机内存中的数据 设计一个扑克牌模拟系统,能够自动洗牌和发牌,系统可以记住发牌的结果, 四个任务 : 1 创建一副牌 2 发牌和洗牌函数 3 改变点数系统适应不同的 ...
- 《Python编程从入门到实践》学习笔记3:列表
1.列表的组成 列表是由一系列按照特定顺序排列的元素组成的有序集合,在Python中,列表需要用'[]'括起来表示,列表中各元素之间需要用','隔开. 作为有序集合,列表在访问的时候,只要知道所需访 ...
- 《Python编程从入门到实践》学习笔记6:字典
字典是Python中的唯一的映射类型,也是一个容器类型.Python的字典能够存储任意个数的Python对象,也包括其他容器类型.创建一个基本的字典,需要包括字典名称,以及用花括号扩起来的键值对,如下 ...
- 《Python编程从入门到实践》学习笔记8(第9章:类)
笔者从昨天开始感觉到了课程的难度,接下来不能简单的概括知识点.笔者将会按照书上的标题章节来整理知识点.这样看起来会更加直观. 9.1 创建类和使用类 9.1.1 创建Dog类 1 class Dog( ...
- 《Python:编程:从入门到实践》学习笔记_第9章 类
第9章 类 根据类来创建对象被称为实例化. 9.1 创建和使用类 使用类几乎可以模拟任何东西. 9.1.1 创建 Dog 类 class Dog(): """一次模拟小狗 ...
- 《Python编程从入门到实践》学习笔记8:函数
Python中的函数就是带名字的代码块,主要用于完成具体的工作.Python的函数用def关键字来声明,定义好函数名后,后面的所金行都属于函数的函数体,如下所示: def test(t1): #def ...
- 《Python编程从入门到实践》学习笔记7:用户输入和while循环
一.用户输入 函数input()的功能,就是让程序在运行过程中,能够接收到用户的输入进行输出,如下例所示: prompt = "请按照提示输入您的姓名,我们将根据您的姓名显示信息!\n&qu ...
- 《Python编程从入门到实践》学习笔记9:类
类是对现实生活中一类具有共同特征的事物的抽象,根据类来创建对象被称为实例化,创建类时,类名首字母要大写完整的类如下例所示 #class声明类,后跟类名,类名首字母需要大写 class Dog():&q ...
最新文章
- 布线时其他区域变黑、高亮Net时其他区域太黑
- java 微信多媒体文件_java微信接口之三—上传多媒体文件
- 各种促销背后的精明算术
- 渗透测试中dns log的使用
- sequelize模型关联_关于Sequelize连接查询时inlude中model和association的区别详解
- PWN-PRACTICE-BUUCTF-5
- ubuntu20.04自带python版本_替换 ubuntu 自带的python版本
- openwrt x86 登录不上_求助,关于OpenWRT外接硬盘不识别的问题
- 选择多级分类_② 供应商管理(分类、评估、选择、绩效、集成、供应商过多的对策、多级供应商管理)...
- unique_ptr智能指针
- java实现阳历农历节以及节假日日期计算
- 2021-09-27 win10 IPV6连接:无网络访问权限 怎么解决
- Openstack集群-Ceph集群作为存储的部署
- 【抓包】- Fiddle软件异常错误,Fiddler Failed to register Fiddler as the system proxy,解决方法
- python众数问题给定含有n个元素的多重集合s_ACM题目:众数给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数.多重集S中重数最大的元素称为众数...
- MSP432学习笔记:ADC14
- 戴尔R730 RAID崩溃 38T数据恢复要多久?
- 小学生加减乘除法做题系统,代码为纯c语言
- 如何打造千万级Feed流系统
- “大促”背后的技术 | 当我们说促销的时候,我们在谈什么?