[Из песочницы] Добавляем MVP в игры на Unity3D
Всем доброго времени суток. В данной статье хотел бы рассказать о том как можно применить шаблон MVP в процессе разработки игр на платформе Unity3D. Использование этого шаблона может способствовать упорядочению кода и улучшению структуры проекта. Стоит сразу отметить, что в статье не дается детального описания самого шаблона, а предполагается наличие у читателя базовых знаний о нем.Как мы все с Вами знаем, MVP — это шаблон призванный отделить презентационную логику от логики приложения. В случае Unity3D, представлением может быть GameObject с набором прикрепленных к нему компонентов, необходимых для реализации презентационной логики (в том числе и компонент самой презентационной логики — MonoBehaviour имплементирующий соответствующий интерфейс представления (View)).В роли презентера (Presenter) может выступать любой тип .NET, реализующий логику определённой части приложения и взаимодействующий с остальными его частями, такими как модели, сервисы и т.д.
Переходим к практикеИтак, предположим перед, нами стоит задача создать очень простую игру в которой игроку представлен не самый широкий арсенал возможных действий: все что он может делать — кликать на изображении цветного прямоугольника. В ответ на действия игрока прямоугольник может прыгать, переворачиваться и изменять свой цвет на произвольный, в зависимости от логики игры. Это очень простой пример, но его вполне достаточно для того чтобы понять каким образом можно применять шаблон MVP при разработке игр на Unity3D.Давайте взглянем на возможный вариант организации проекта приведенный на следующем рисунке:
Обратите внимание на скрипт FunnyRectView в списке компонентов объекта FunnyRect. Этот скрипт — реализация презентационной функциональности. Тип FunnyRectView имплементирует интерфейс IFunnyRectView, а так же, этот интерфейс активно используется презентером для взаимодействия с представлением.
Ниже приведен код FunnyRectView.
public class FunnyRectView: MonoBehaviour, IFunnyRectView { private readonly IFunnyRectPresenter _presenter; public FunnyRectView () { _presenter = new FunnyRectPresenter (this); } public void Awake () { _presenter.Initialize (); } } Связка представления с презентером происходит в конструкторе. Презентер, в качестве параметра конструктора принимает ссылку типа IFunnyRectView. Этот интерфейс и служит тем мостом который соединяет представление с презентером. Он позволяет вызывать методы определенные в FunnyRectView, подписываться и реагировать на его события. Представление так же имеет возможность взаимодействовать с презентером через сохраненную в _presenter ссылку.Давайте добавим необходимую для нормального функционирования логику в FunnyRectView.
public class FunnyRectView: MonoBehaviour, IFunnyRectView
{
private readonly IFunnyRectPresenter _presenter;
private bool _isInputEnabled;
private Animator _animator;
private const string JumpAnimationTriggerName = «JumpTrigger»;
private const string RotateAnimationTriggerName = «RotateTrigger»;
public FunnyRectView ()
{
_presenter = new FunnyRectPresenter (this);
}
public void Awake ()
{
_animator = gameObject.GetComponent
public interface IFunnyRectView { event EventHandler RotationEnd; event EventHandler JumpEnd; event EventHandler Clicked; void EnableInput (); void DisableInput (); void Rotate (); void Jump (); void ChangeColor (Color color); } IFunnyRectPresenter: public interface IFunnyRectPresenter { void Initialize (); void Uninitialize (); } Применение MVP дало нам возможность в последующем изменять презентационную логику по нашему усмотрению не оказывая влияния на логику приложения. Так же необходимо заметить, что исходя из концепций MVP, необходимо избегать прямого вызова методов и установки свойств презентера из представления. Вместо этого его нужно уведомлять о наступлении тех или иных событий.Полный исходный код с коментариями можно взять на github.com/rumyancevpavel/FunnyRect.