Ilingis 发表于 2022-4-24 17:53

Unity3D常用设计模式《工厂模式》


工厂模式(Factory Pattern)是游戏开发中比较常用的设计模式。这种类型的设计模式属于创建型模式,它提供了一种创建对象实例的最佳方式。在工厂模式中,我们在创建对象时不会对用户暴露创建对象的具体细节,而是通过提供一个共同的接口来创建需要的对象。

如果不好理解,先来看看生活中的一个真实案例。例如某个品牌的汽车制造工厂,对外提供生产这个品牌的不同型号汽车的服务。外界只要指定一个“汽车型号”,工厂就可以根据型号来构建出对应型号的汽车。这样外界就不用关心工厂的内部是如何运作的,也不需要。当用户需要某个型号的汽车的时候,调用工厂的接口就可以了。同时工厂内部的机制,可以任意的修改,比如增加了一个新的汽车型号的服务等等。

通过上面的例子,我们来分析一下工厂模式的几个重要的元素,掌握这几个元素,你就可以非常方便的在你的游戏项目中使用工厂模式。

首先是要定义和规划我们工厂模式要创建出来的对象,我们可以称之为“工厂元素”。这些工厂元素都属于不同的类型(上面例子中的不同型号的某品牌汽车),这些类型都属于同一个基类(某品牌汽车,具有汽车的通用功能)。所以工厂元素的设计规划就是基类+子类的模式,基类提供对外使用的接口(如汽车的功能),而子类在保证实现通用的接口基础上,还可以实现自己不同的特性。如果要增加一种新的类型的元素,那么新的类型的元素只要继承自这个基类就可以了。

工厂元素设计好了以后,接下来就是提供一个“工厂构造接口”来构造不同的类型的实例,一般我们会提供一个Create接口,用户传递一个标识元素类型的参数,Create里面会根据用户传递的类型来new不同的子类实例,返回一个基类的引用,让基类指向子类的实例。如图:

用户就可以通过工厂类来管理各个工厂元素子类的实例。当我们新加一种元素类型的时候,新的工厂元素只要继承自基类,然后在工厂的Create接口的实现里面加一个类型并且new这个新类的实例就可以了。

介绍完工厂模式后,相信大家对工厂模式已经有所了解了。接下来我们通过地图上战斗单元的设计来讲解一下我们整个战斗系统中如何使用工厂模式来处理敌人小怪的生成逻辑。

步骤1定义一个怪物的基类

class BaseEnemy extends MonoBehaviour {
// 攻击接口
// end
// 行走接口
// end ….
}

步骤2定义具体战斗单元的子类FlyEnemy

FlyEnemy和MonestEnemy,重载实现具体的接口

class FlyEnemy extends BaseEnemy {
// …
}

class MonestEnemy extends BaseEnemy {

// …
}

步骤3编写工厂模式的Create接口

class EnemyFactory {
public static BaseEnemy AddEnemyComponent(GameObject obj, int enmeyType) {
    switch(enemyType) {
      case eFlyEnemy:
      return obj.AddComponent<FlyEnmey>();
      break;
      case eMonestEnemy:
      return obj.AddComponent<MonestEnemy> ();
      break;
      …
    }
}
}

步骤4根据Excel表格描述与地图数据来生成敌人

敌人类型描述表,如图:

地图数据描述表,如图:

我们编写地图管理代码,读取地图表格数据,获得地图上敌人的类型、资源路径、位置、缩放、旋转,然后我们根据描述来在地图上创建敌人,代码如下:

GameObject obj = GameObject.Instantiate(资源路径对应的预制体);
obj.transform.position = new Vector3(配置表读取的位置);

// 通过工厂模式把敌人构建出来
BaseEenemy enemy = EnemyFactory.AddEnemyComponent(obj, 配置表读取的type);

这样我们就可以把地图上的不同类型的敌人都创建出来了。如果有新的类型的敌人,这边的逻辑都不用改,只需要加一种类型,加一个子类就可以了。这就是工厂模式在游戏中的使用,很有用。

当然,这个只是工厂模式的一种最简单的应用场景,实际上工厂模式还有很多其它的形式和变种,要针对具体的需要进行变更。工厂模式最核心的思想就是隐藏创建细节。
页: [1]
查看完整版本: Unity3D常用设计模式《工厂模式》