Skip to content
Dimitry edited this page Dec 9, 2018 · 1 revision

Паттерн Фабрика

Фабрики - это SO ( Scriptable Object ) отвечающие за создание сложных композиций сущностей. Например фабрика врагов будет отвечать за создание сущностей врагов, а фабрика игрока за добавление героя и его интерфейса. Фабрики не являются обязательным элементом однако позволяют сделать код чище за счет убирания шаблонного кода создания различных сущностей. Помимо прочего будучи ассетом фабрика может хранить различные переменные настроек и префабов.

Так как природа фреймворка основана на главенстве композиции - фабрики идеальные кандидаты для сборки сущностей с добавлением различного функционала на лету : например через фабрику мы можем попросить создать разновидность меча который умеет говорить и давать задания.

Фабрики добавляются в Starter классы в лист Factory. Оттуда стартер добавляет их в Toolbox.

Настройка фабрик

Настройка фабрик 2

// где-то в игре создаем героя
   Toolbox.Get<FactoryPlayer>().Spawn<ActorPlayer>(spawner.selfTransform.position, Quaternion.identity);
// что стоит за строчкой выше
namespace Homebrew
{
    [CreateAssetMenu(fileName = "Factory Player", menuName = "Actors/Factories/Player")]
    public class FactoryPlayer : Factory
    {
       public GameObject prefabPlayer;
       public GameObject prefabPlayerUI;
       public GameObject prefabPlayerUIMelee;

        public override T Spawn<T>(Vector3 pos, Quaternion rot)
        {
            T go = null;
            if (typeof(T) == typeof(ActorPlayer))
            {
                CreateUI();
                go = this.Populate<T>(Pool.Entities, prefabPlayer, pos, rot);
            }

            return go;
        }

        void CreateUI()
        {
            this.Populate(Pool.UI, prefabPlayerUI);
            this.Populate(Pool.UI, prefabPlayerUIMelee);
        }
    }
}

Вы можете использовать свои методы Spawn внутри фабрики.( не обязательно использовать override T Spawn метод )

Как создавать фабрики

Процесс создания фабрик такой же как и любых SO.

Однако в фреймворке есть быстрый метод автогенерации. Кликните ( выделите ) папку [1]Source или ту папку в которой вы храните код. После этого жмите Tools->Actors->Add->Factory Создание фабрики

Внутри папки Source появится скрипт- в зависимости от того как вы его назовете он появится в создании ассетов. Чтобы создать новый ассет выберете папку где вы храните ассеты. По умолчанию это [2]Content/Resources/Data ПКМ по папке и Create->Actors->Factories->Название Фабрики. После этого ваш ассет будет создан.

Обычный способ создания фабрики будет ручное написание скрипта фабрики:

// добавляем атрибут CreateAssetMenu 
// fileName - как по умолчанию называется новый ассет.
// menuName - откуда в меню создания мы будет выбирать ассет.
  [CreateAssetMenu(fileName = "Factory Player", menuName = "Actors/Factories/Player")]
// наследуемся от Factory   
 public class FactoryPlayer : Factory
    {

Обновление фабрик

Фабрики теперь наследуются от синглтона типа Factory<T> Например :

public class FactoryPlayer : Factory<FactoryPlayer>

Все методы к которым мы хотим обращаться нужно делать статичными:

public static T Spawn<T>(Vector3 pos, Quaternion rot) where T : class
		{
			T go = default(T);
			if (typeof(T) == typeof(ActorPlayer))
			{
				Default.CreateUI();
				go = Default.Populate<T>(Pool.Entities, Default.prefabPlayer, pos, rot);
			}

			return go;
		}

Переменная Default - это "синглтон" фабрики.

Это позволит обращаться к фабрикам вот так:

	FactoryPlayer.Spawn<ActorPlayer>(transform.position, Quaternion.identity);

Вместо

var factory = Toolbox.Get<FactoryPlayer>();
factory.Spawn<ActorPlayer>(transform.position, Quaternion.identity);

PS. Добавлять фабрики в стартеры в любом случае необходимо.