Factory pattern. Пример применения в Unity

от автора

Фабричных методов на самом деле много.
Даже базовые конструкции if else являются фабричным методом, так как и switch.
Но ведь это не удобно читать и расширять.

Представим простой пример. У нас есть игра slasher с монстрами. У нас есть несколько режимов: easy, medium, hard. Следовательно пусть у нас будут отличаться у монстров жизни и урон. Как организовать удобное создание монстров и в одном месте? Все в подcut`e.

1. Создадим примерное описание монстра в виде Description.

[Serializable] public class MobDescription {     public float MaxHealth;     public float Damage; } 

2. Заполним наших монстров по уровням

Способов заполнить такие Descriptions на самом деле много, будь то json, xml или же просто ScriptableObject. Для примера воспользуемся ScriptableObject и создадим класс списков описаний монстров.

[CreateAssetMenu(fileName = "MobDescriptions", menuName = "MobDescriptions", order = 51)] public class MobDescriptions : ScriptableObject {     [SerializeField] private List<MobDescription> _listOgre;     [SerializeField] private List<MobDescription> _listTroll;      public List<MobDescription> ListOgre => _listOgre;     public List<MobDescription> ListTroll => _listTroll; }

И получим вот это.

Так как мы делаем 3 уровня сложности, то давайте заполним

Хорошо у нас теперь есть все описания по уровням сложности для наших монстров.

3. Создадим Model для mvc монстра.

Это лишь шаблон использования расширения модели, для того чтобы не хранить данные о монстре прямо в модели.

public class MobModel {     private MobDescription _description;     private float _currentHealth;      public MobDescription Description => _description;      public MobModel(MobDescription description){         _description = description;         _currentHealth = _description.MaxHealth;     }      // Ваша логика монстра }

4. Теперь создадим класс фабрики, которая будет создавать монстров в зависимости от уровня сложности. Такую фабрику легко расширить, а так же добавлять другие фабрики для генерацию дропа или спавна объектов.

public class Factory {     private Dictionary<string, Func<int, MobModel>> mobFactory;      public void Init(MobDescriptions descriptions)     {         mobFactory = new Dictionary<string, Func<int, MobModel>>()         {             {"ogre", (level) => new MobModel(descriptions.ListOgre[level])},             {"troll", (level) => new MobModel(descriptions.ListTroll[level])}         };      }      public MobModel CreateMobModel(string nameMob, int level)     {         return mobFactory[nameMob](level);     } }

5. Ну и конечно же пример вызова создания монстра.

Пока нет никакой логики используем хардкод. В итоговом варианты это может быть доп описание уровня, в котором будут параметры для спавна монстров с нормальными условиями. Например когда игрок прошел конкретную точку, спавнятся N enemy X уровня.

public class GameManager : MonoBehaviour {     [SerializeField] private MobDescriptions _mobDescriptions;      private Factory _factory;      private void Start()     {         _factory = new Factory();         _factory.Init(_mobDescriptions);          _factory.CreateMobModel("ogre", 2);     } }


ссылка на оригинал статьи https://habr.com/ru/post/482402/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *