В данной статье описан путь создания Unity приложение с возможностью безболезненного расширения. Не все описанные методы стоит применять во время участия в "GameJam" в частности внедрение ID контейнеров, не всегда рационально занятие, поскольку требует дополнительных абстракций, на продувание которых в рамках геймджема может не оказаться времени.
Приведенный ниже код будет с каждой итерацией усложняться, таким образом показывая рост квалификации
Начало:
Описание "Игры": ГГ это куб которого преследует шары.
Первым делом создадим скрипт (рис 1.) для нашего героя, в котором будут считываться нажатые клавиши.
Рис.1 Hero.csДалее создадим скрипт (рис 2.) для нашего шара который будет догонять игрока. Игрок передается как объект, с целью получения текших координат.
Рис.2 Bot.cs
На рисунке 3 представлена демонстрация работы двух скриптов.
Рис.3 Демонстрация работы двух скриптов.
Далее увеличим количество NPC для последующих демонстраций Рис. 4. без использования фабрик или DI
Расширение:
После добавления такого большого количества NPC стало понятно, что силы не равны, поэтому был создан второй герой который умел "отгонять" NPC на позицию (0,0,0). С реализацией можно ознакомиться на рисунке 5. Теперь у героя появился метод GetPosition, благодаря которому он может не только сообщать верные координаты, но также и ошибочные.
Рис.5 HeroAssasin.cs
Замете что мы передаем в класс HerroAssasin, а не объект. При этом в в инспекторе мы передаем объект из которого достается автоматически ссылка на скрипт. (Рис. 7) с демонстрацией можно ознакомиться на рисунке 8.
Расширение 2:
Каждый раз наследоваться от общего класса не удобно, поскольку в гигантском ворохе наследования очень легко запутаться. Именно в момент когда наследование становиться чуть сложнее чем в примере выше стоит перейти на интерфейсы. К сожалению в юните вы не можете передать через инспектор что либо в интерфейс. И именно в этот момент на помощь приходит Extenject. https://github.com/modesttree/Zenject/releases/tag/9.2.0
Extenject
Extenject реализует инверсию управления.
Следующая диаграмма показывает, как обычно работают сильно связанные компоненты:
ClassA
напрямую зависит от ServiceA/ServiceB
. Это обременяет независимое тестирование ClassA
необходимостью заботиться о деталях реализации этих двух служб.
Внедрение зависимостей (DI — Dependency Injection) — это подход к реализации инверсии управления. На следующем рисунке показан предыдущий пример с использованием внедрения зависимостей:
Внедрение зависимостей используется как строитель (Builder
) для генерации нашего ClassA
, проверки необходимых зависимостей и их автоматического предоставления. ClassA
не заботит то, какой конкретно класс, реализующий требуемый интерфейс, используется, пока таковой имеется в наличии.