Поиск…


Модельный шаблон контроллера модели (MVC)

Контроллер представления модели является очень распространенным шаблоном проектирования, который существует уже довольно давно. Этот шаблон фокусируется на сокращении кода спагетти путем разделения классов на функциональные части. Недавно я экспериментировал с этим шаблоном проектирования в Unity и хотел бы изложить основной пример.

Конструкция MVC состоит из трех основных частей: модели, вида и контроллера.


Модель: модель представляет собой класс, представляющий часть данных вашего объекта. Это может быть игрок, инвентарь или весь уровень. Если вы правильно запрограммировали, вы сможете использовать этот скрипт и использовать его за пределами Unity.

Обратите внимание на несколько вещей о модели:

  • Он не должен наследовать от Monobehaviour
  • Он не должен содержать специальный код Unity для переносимости
  • Поскольку мы избегаем вызовов Unity API, это может помешать вещам вроде неявных преобразователей в классе Model (обходные пути необходимы)

Player.cs

using System;

public class Player
{
    public delegate void PositionEvent(Vector3 position);
    public event PositionEvent OnPositionChanged;

    public Vector3 position 
    {
        get 
        {
            return _position;
        }
        set 
        {
            if (_position != value) {
                _position = value;
                if (OnPositionChanged != null) {
                    OnPositionChanged(value);
                }
            }
        }
    }
    private Vector3 _position;
}

Vector3.cs

Пользовательский класс Vector3 для использования с нашей моделью данных.

using System;

public class Vector3
{
    public float x;
    public float y;
    public float z;

    public Vector3(float x, float y, float z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }
}

Вид: представление представляет собой класс, представляющий часть просмотра, привязанную к модели. Это подходящий класс для выхода из Monobehaviour. Это должно содержать код, который взаимодействует напрямую с отдельными API-интерфейсами Unity, включая OnCollisinEnter , Start , Update и т. Д. ...

  • Обычно наследуется от Monobehaviour
  • Содержит специальный код Unity

PlayerView.cs

using UnityEngine;

public class PlayerView : Monobehaviour
{
    public void SetPosition(Vector3 position)
    {
        transform.position = position;
    }
}

Контроллер: контроллер - это класс, который связывает вместе и модель, и представление. Контроллеры поддерживают синхронизацию модели и представления, а также взаимодействие с приводом. Контроллер может прослушивать события от одного из партнеров и обновлять соответственно.

  • Привязывает как модель, так и представление по состоянию синхронизации
  • Может управлять взаимодействием между партнерами
  • Контроллеры могут быть или не быть переносимыми (вам может потребоваться использовать код Unity здесь)
  • Если вы решили не переносить свой контроллер портативным, подумайте над тем, чтобы сделать его Monobehaviour, чтобы помочь с проверкой редактора

PlayerController.cs

using System;

public class PlayerController
{
    public Player model { get; private set; }
    public PlayerView view { get; private set; }

    public PlayerController(Player model, PlayerView view)
    {
        this.model = model;
        this.view = view;

        this.model.OnPositionChanged += OnPositionChanged;
    }

    private void OnPositionChanged(Vector3 position)
    {
        // Sync
        Vector3 pos = this.model.position;

        // Unity call required here! (we lost portability)
        this.view.SetPosition(new UnityEngine.Vector3(pos.x, pos.y, pos.z));
    }
    
    // Calling this will fire the OnPositionChanged event 
    private void SetPosition(Vector3 position)
    {
        this.model.position = position;
    }
}

Конечное использование

Теперь, когда у нас есть все основные части, мы можем создать завод, который будет генерировать все три части.

PlayerFactory.cs

using System;

public class PlayerFactory
{
    public PlayerController controller { get; private set; }
    public Player model { get; private set; }
    public PlayerView view { get; private set; }

    public void Load()
    {
        // Put the Player prefab inside the 'Resources' folder
        // Make sure it has the 'PlayerView' Component attached
        GameObject prefab = Resources.Load<GameObject>("Player");
        GameObject instance = GameObject.Instantiate<GameObject>(prefab);
        this.model = new Player();
        this.view = instance.GetComponent<PlayerView>();
        this.controller = new PlayerController(model, view);
    }
}

И, наконец, мы можем вызвать фабрику у менеджера ...

Manager.cs

using UnityEngine;

public class Manager : Monobehaviour
{
    [ContextMenu("Load Player")]
    private void LoadPlayer()
    {
        new PlayerFactory().Load();
    }
}

Прикрепите скрипт Manager к пустому GameObject в сцене, щелкните правой кнопкой мыши компонент и выберите «Загрузить проигрыватель».

Для более сложной логики вы можете ввести наследование с абстрактными базовыми классами и интерфейсами для улучшенной архитектуры.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow