游戏开发中,逻辑与渲染的分离

回顾之前做的几个战斗Demo,有所得。

一、做法:

为了更清晰,NRatel将游戏对象类拆分为两个类,如下:

1、定义“纯粹的逻辑类”。
基本职责:对游戏对象的“逻辑值”进行定义、存储和计算。
关键要素:只关心逻辑数据,不考虑渲染问题。(如同在没有渲染能力的服务端写代码)。
不用继承Monobehaviour(Unity中)、不在任何系统自带的组件上存取逻辑值。
在逻辑运算的特定的位置抛出数据变更事件。
举例说明:如定义、存储和计算“变换相关的坐标、旋转、缩放”、“战斗属性相关的“生命、法力”等。

2、定义“纯粹的渲染类”。
基本职责:根据逻辑类中的数据,对物体进行实际显示更新。
关键要素:持有实际的游戏物体(GameObject)。(获得游戏物体的对象引用)
持有对应的逻辑类。(获得对应逻辑类的对象引用)
渲染类监听逻辑类中的数据变更事件,并以此对要渲染的游戏对象及其子对象做显示更新(逻辑类和渲染类,是一种观察模式的单向弱依赖)。
举例说明:如监听事件,对Transform组件上的值进行修改(直接赋值或平滑插值)。

实际开发中,这两个类其实是可以合并为一个类的,只是要注意保持这种观察处理的方式

二、意义(为什么要将逻辑与渲染分离)

1、清晰的数据模型、可拆卸的渲染逻辑(提高系统性能)。
渲染观察于逻辑(单向弱依赖),所以,
能够随意销毁任何显示中的游戏物体(GameObject)而不影响逻辑运算(逻辑类一直存在,只是干掉了观察者)。对于“按视野显示游戏物体,分质量显示游戏物体” 这样的性能优化需求,可以处理的得心应手。

2、始终拥有安全可靠的数据。
所有数据都是自己显式定义的,不存储在任何系统组件上,所以,
能够避免“意想不到的被修改”(比如被一些tween类插件意外修改)。
能够为“帧同步中处理浮点数精度问题”提供基本条件(系统组件上的有些值是浮点数,逻辑值存储在组件上,将无法处理)。