Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

2.7 高频对象与重表现型游戏问题模型

当游戏场景中同时存在大量动态对象(数千个子弹、数百个粒子、上百个单位)时,即使单个对象的逻辑很简单,总量的叠加也会导致严重的性能问题。这类游戏的挑战不在网络或分布式架构,而在客户端和服务器端的计算效率

典型场景:弹幕射击(东方Project、怒首领蜂)、RTS(星际争霸、魔兽争霸——同屏上百个单位)、割草类游戏(吸血鬼幸存者)、大型粒子特效场景。

三个核心问题

问题1:大量对象管理

当一个场景中有数千个活跃对象时,传统的面向对象管理方式(每个对象一个类实例,包含自己的更新逻辑和渲染逻辑)会遇到问题:

  • 内存分配开销:频繁创建和销毁对象(如子弹发射和消失)导致大量内存分配,触发 GC/内存碎片
  • 缓存不友好:面向对象的数据分散在内存各处,CPU 缓存命中率低
  • 更新开销:即使大多数对象的行为相同(如所有子弹都是直线运动),也要逐个调用虚函数

ECS(Entity-Component-System)架构

ECS 是解决大量对象管理的主流方案。核心思想是将“数据“和“逻辑“分离:

  • Entity(实体):只是一个 ID,没有数据也没有逻辑
  • Component(组件):纯数据,如 Position 组件、Velocity 组件、Health 组件
  • System(系统):纯逻辑,遍历拥有特定组件组合的实体,执行更新。如 MovementSystem 遍历所有有 Position + Velocity 组件的实体,更新位置

这样做的性能优势:

  • 数据连续存储:相同类型的组件存储在连续内存中(Structure of Arrays),CPU 缓存友好
  • 批量处理:System 可以对一组数据做批量操作,适合 SIMD 优化
  • 无虚函数调用:System 直接操作数据数组,无间接调用开销

参考:ECS 架构在游戏开发中的应用,最知名的实践是 Unity 的 DOTS(Data-Oriented Technology Stack)。Unity 官方文档对 ECS 的设计理念和性能优势有详细说明。 — Unity DOTS 文档 [待补充具体链接]

参考:GDC 上有多场关于 ECS 架构的演讲,其中 Overwatch 团队分享了他们如何使用 ECS 架构来管理大量游戏对象。 — 相关 GDC 演讲可通过 GDC Vault 搜索 “ECS” [待补充]

对象池(Object Pool)

对于频繁创建和销毁的对象(如子弹、粒子),使用对象池来复用内存:

  • 预分配一批对象,初始化为“未使用“状态
  • 需要新对象时从池中取一个,而非 new/malloc
  • 对象“销毁“时归还池中,而非 delete/free

这在几乎所有游戏引擎中都是标配优化。关键细节:

  • 池大小需要预估峰值使用量,太小不够用,太大浪费内存
  • 归还池中时必须正确重置所有状态,否则会导致“脏数据“bug
  • 在多线程环境下需要加锁或使用 per-thread 池

问题2:碰撞检测优化

当有 N 个对象时,朴素的两两碰撞检测复杂度是 O(N²)。当 N 达到数千时,每帧的碰撞检测会成为瓶颈。

空间划分加速

核心思想:只检查“可能在空间上接近“的对象对。

  • 网格划分:将空间划分为等大小的格子,每个对象属于某个格子。只检查同格子和相邻格子中的对象对。与 MMO 的 AOI 九宫格原理相同。适用于对象分布相对均匀的场景。
  • 四叉树:递归划分空间,每个节点只包含少量对象。适用于对象分布不均匀的场景(如集中在某些区域)。
  • 排序扫描(Sweep and Prune):将所有对象按某个轴(如 X 轴)排序,只对 X 轴上重叠的对象对做完整的碰撞检测。减少候选对数量的效率很高。

Broad Phase vs Narrow Phase

实际的碰撞检测系统通常分为两阶段:

  1. Broad Phase(粗检测):用空间划分算法快速排除不可能碰撞的对象对,生成“候选对“列表
  2. Narrow Phase(精检测):对候选对做精确的几何碰撞判定

Broad Phase 的目标是将 O(N²) 降到接近 O(N log N) 甚至 O(N)。

问题3:服务器端的考量

对于弹幕射击等纯单机游戏,上述问题完全在客户端解决。但如果游戏是联网的(如多人割草、RTS),服务器也需要处理大量对象。

服务器端需要考虑的额外问题:

  • 同步带宽:数千个对象的状态不能全部广播给客户端。需要增量更新(只发送变化的属性)和区域过滤(只发送玩家视野范围内的对象)
  • 服务器端碰撞:对于有 PvP 的游戏,碰撞判定必须在服务器端执行(防作弊),但服务器端的碰撞检测效率直接影响单服承载能力
  • 确定性模拟:如果采用帧同步模式,所有客户端的模拟必须严格确定性,这对浮点运算有严格要求

小结

  1. 大量对象管理 → ECS 架构 + 对象池,核心思想是数据导向设计
  2. 碰撞检测 → 空间划分加速(网格/四叉树/排序扫描),Broad Phase + Narrow Phase 两阶段策略
  3. 联网场景 → 服务器端需要同样高效的碰撞检测和状态管理,同时考虑带宽优化

这类问题在游戏引擎层面有成熟的解决方案,本节仅从问题模型角度概述。具体实现将在第10章(客户端技术)和第22章(引擎选择)中深入讨论。


参考文献

本章聚焦问题模型分析。ECS 架构、碰撞检测算法的具体实现将在后续章节展开。关于 ECS 的工业实践,Unity DOTS 文档和相关 GDC 演讲是较好的参考来源。