《游戏编程模式》三、享元模式(Unity 实现)

使用共享以高效地支持大量的细粒度对象。

适用场景:

  • 有太多对象并考虑对其进行轻量化

3.1 森林之树

为了在屏幕上渲染出森林,所有的(树)数据必须按照一定的方式进行组织并沿着总线从 CPU 传送到 GPU 里去

  • 一个多边形网格:定义了树干、树枝和树叶的几何描述
  • 树皮和树叶的纹理
  • 树在森林中的位置以及朝向
  • 调节参数:如大小、颜色等,以使每棵树看起来都不一样

虽然森林中有成千上万的树木,但它们大部分看起来是相似的。它们可能会全部使用相同的网格和纹理数据

我们将对象侵害成两个独立的类------通用数据特殊数据

通用数据:

cs 复制代码
class TreeModel
{
    private Mesh mesh;
    private Texture bark;
    private Texture leaves;
}

整个游戏只需要一份这样的数据,然后游戏世界中每棵树的实例都有一个指向共享的 TreeModel 的引用

cs 复制代码
class Tree
{
    private TreeModel model;
    
    private Vector3 position;
    private float height;
    //...
}

将数据存储在内在中是个好办法,但对渲染毫无助益。在显示之前,森林数据还是必须按照一定的格式上传到 GPU 中,我们需要用显卡能够识别的方式来表达这种资源共享

3.2 一千个实例

为了最大程度地减少发送到 GPU 上的数据量,我们希望

  • 只发送一次共享数据------TreeModel
  • 再单独将每棵树的特殊数据上传
  • 告诉 GPU:使用那个共享模型来渲染每个实例

3.3 享元模式

有太多对象并考虑对其进行轻量化时它便能派上用场

3.4 扎根之地

地面也要在我们的游戏中被表示出来。如草地、泥土、丘陵、湖泊==,我们将使用基于瓦片(Tile-based)的技术来构建地面,地面是一个由许多细小瓦片组成的巨大网格,每块瓦片都由某种地形所覆盖

cs 复制代码
class Terrain
{
    private int moveCost;
    private bool isWater;
    private Texture texture;
    
    Terrain(int moveCost, bool isWater, Texture texture) { ... }
    //...
}

但我们不希望为每块瓦片构建地形实例付出成本,因为同类的地形实例是相同的

cs 复制代码
class World
{
    private Terrain[,] tiles = new Terrain[width, height];
    //...
}

每个相同地形的瓦片都会引用相同的地形实例

相关推荐
vker37 分钟前
第 1 天:单例模式(Singleton Pattern)—— 创建型模式
java·设计模式
晨米酱19 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机1 天前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机1 天前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机1 天前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机1 天前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤1 天前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机2 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机2 天前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
烛阴2 天前
【TS 设计模式完全指南】懒加载、缓存与权限控制:代理模式在 TypeScript 中的三大妙用
javascript·设计模式·typescript