事件机制
对象的生命周期问题会导致一些游戏的bug。比如这一帧要调用的go,实际在上一帧就销毁了。
事件定义
事件类型和事件参数
事件注册
对象强引用(object strong reference):对象注册在这就不能删除,保证整个引用的安全性。会导致内存越来越大。
wake reference:增加额外一步判断物体是否被删掉。
事件分发
直接派发(马上处理)
方式:收到消息,直接就处理。
可能会导致帧率不稳定,不能并行处理消息
事件队列(下一帧处理)
Event Queue 事件队列
方式:收到消息需要先存到队列里,不会立即调用。
- 把所有需要运行的event全部catch一起,变成一个q,然后下一帧全部处理。
- 把几百个event拍成q和把q变成几百个event,序列化和反序列化。
这么做是为了保证消息的正确和完整设计了一个队列
用ring buffer的方法管理event queue的池子。
进一步可以把event的功能再区分,比如NetEventManager、CombatEventManager、AnimationEventManager等。
产生的问题
问题1:事件处理顺序无法确定。
消息执行的顺序无法保证(很多的引擎会把不同系统的处理顺序给定死,比如有时需要先处理动画在处理物理等。)
这个问题非常难解决
现代引擎中,通常会有三种tick去支持。下一帧一上来就处理完,有的是在post tick处理,有的在pre tick 处理,有的是immediate处理
问题2:事件的递进式关系。
event的处理机制一般会是在下一帧去处理的。
假设一个简单的递进关系,eventA触发eventB,eventB触发eventC(比如砍人一刀会飙血,那会希望在同一帧下屏幕会有渲染飙血的效果)。
这里就需要用一些hard core去专门处理这个问题。
游戏逻辑与脚本系统
编译语言
早期的引擎直接采用C/C++,这类原生的编译语言进行代码的编写。
编译语言:编译成高性能的机器码,比汇编语言更易于使用。
游戏需求随着硬件的发展而变得复杂,需要快速迭代游戏逻辑
编译语言的问题:
- 问题1:即使稍作修改也需要重新编译(每改一个gameplay,游戏引擎就得全部渲染一遍)
- 问题2:如果代码不正确,程序很容易崩溃(游戏发布后会有bug)
- 问题3:游戏玩法定义的设计师,无法直接更改代码
问题1、2解决方案:hot update 热更新
问题3解决方案:脚本语言
脚本语言
脚本语言是一种解释语言。
支持热更新;能够快速修改迭代;中间某个函数换掉后,还能继续运行;不会把本体crush掉。
写非常复杂的网络服务器端时常用。

- 脚本文本通过自己的编译器,变成一堆的bytecode,用一个虚拟机执行bytecode,就可以跑起来了。相当于在游戏系统上运行了一个自己的虚拟机。
Lua
在魔兽世界、文明5中使用。
优点:稳健且成熟;出色的运行时性能;重量轻,可扩展性强
缺点:库很轻量级,啥没有要自己写。
Python
在模拟人生4:EVE Online使用。
优点:支持反射;内置的面向对象支持;拥有广泛的标准库和第三方模块
C#
脱机字节码,在Unity中使用,把C#这样的原生语言变成一个脚本语言使用。
优点:学习曲线低,易读易懂;内置的面向对象支持;社区环境好,有很多活跃的开发者
Lua、C#和Python比较
省内存:Lua>C#>Python
运行速度:C#>Lua>Python
热更新
脚本语言的热更新,就是把函数指针给修改掉。
老的函数有个函数指针,在扩这个函数时,把函数指针重新指向新的脚本即可。
脚本语言的坏处: 运行效率慢。
just in time:可以一边执行一边编译。(比如大名鼎鼎的lua)
脚本与引擎之间的对象管理
引擎使用原生编译语言比如C++编写,gameplay部分用脚本语言编写。对于游戏中的对象,对象归谁管,取决于游戏本身。
- 如果本身游戏的对象没有那么多,但是有重度的角色细节的表现(比如动作、Ai等),比如MMO。把生命周期交给引擎管理。
- 如果玩法非常多、人物也非常多,玩法还会产生很多的人物,比如MMORPG。一般把生命周期交给脚本管理。这样在玩法系统中可以很容易的生成和销毁非常多的对象。
脚本系统的体系结构
引擎包脚本:
- 引擎调用脚本,到了某个特定的、比如component时,把那段相应的处理写成脚本。
- 比如unity(原生态就是每个component可以拓展成一个脚本,用C#)
脚本包引擎:
- 早期有些游戏会用到,现在很少用。
- 把引擎单纯当成要给sdk库,引擎提供了各种各样的服务,然后由脚本控制整个tick的flow,引擎把所有的go给tick一遍,到了系统休息,脚本给份名单,引擎再根据把所有的go给干掉。
可视化脚本
UE的Blueprint 蓝图系统,unity的Visual Scripting。
对于一些设计师、无程序学习背景的人,可视化脚本非常方便。
Visualscript也是一种程序设计语言,它通常需要变量、声明与表达、控制流、功能、类(面向对象的程序设计语言)。
- 用不同颜色的“拐角”来定义不同的数据类型。
- 使用“节点”表示语句和表达式。
- 通过“执行引脚”使用执行线来使语句顺序排列。
可视化脚本的问题:
- 工业化应用时,速度不够
- 脚本多时,会变成“蜘蛛网”
- 目前大多数都是,直接把Visual Scripting变成Bytecode,然后在虚拟机上跑。
3C系统
3C:角色、控制、相机
3C是最直接的操作体验的核心。
Control:Aim Assist、Feedback
Camer:PoV(位置)和FoV(张角)
QA补充
有些平台不允许热更:
审核时的内容通过,后续热更的内容不通过
……