MVP no Unity ou como simplificar a vida

(Fixo)


Primeiro, vamos ver o que é o MVP (Model View Presenter).


Por que é necessário? A resposta mais simples é construir uma arquitetura conveniente e extensível.


Vale a pena descobrir por que você precisa dividir a interação em três classes diferentes. Primeiro, a separação de tarefas, seguindo os princípios do SOLID. Em segundo lugar, para facilitar a interação com os servidores para sincronização de dados.


Vamos dar uma olhada nas responsabilidades do exemplo


PlayerView.cs - representa em particular a classe MonoBehaviour


using UnityEngine; public class PlayerView : MonoBehaviour { } 

PlayerModel.cs - representa uma classe de dados


 public class PlayerModel { } 

Presenter.cs - representa uma classe de conectividade entre modelo e exibição


 public class PlayerPresenter { private PlayerView _playerView; private PlayerModel _playerModel public PlayerController(PlayerView view, PlayerModel model) { _playerView = view; _playerModel = model; } } 

Esse é o padrão inteiro.


Agora vamos ver por que tudo isso é necessário.


Adicionamos PlayerView.cs como um componente ao nosso player Prefab .


As demais classes são criadas em alguma classe de controle. Por exemplo, crie uma classe de controle.


Crie um objeto vazio no palco e desligue o componente GameManager


GameManager.cs


 public class GameManager : MonoBehaviour { public GameObject _playerPrefab; private PlayerPresenter _playerController; private PlayerModel _playerModel; public void Start(){ _playerModel = new PlayerModel(); var playerObject = Instantiate(_playerPrefab, Vector3.zero,Quaternion.identity); var playerView = playerObject.GetComponent<Playerview>(); _playerPresenter = new PlayerPresenter(playerView, _playermodel) } } 

Bem, agora no início do jogo, criaremos um jogador. Mas o que vem depois?


De fato, este é um mecânico de fantasia. Bem, por exemplo, vamos expandir o modelo do Player adicionando integridade.


PlayerModel.cs


 public class PlayerModel { public event Action Death; public event Action<float> ChangedHealth; private float _maxHp = 100; private float _currentHp; public PlayerModel(){ _currentHp = maxHp; } public void SetNewHealth(float damage) { _currentHp -= damage; if(_currentHp > 0) ChangedHealth?.Invoke(_currentHp); else Death?.Invoke(); } } 

Agora, nosso jogador tem Vida e dois eventos para mudar saúde e morte. Ou seja, Modelo - representa a concentração de todos os dados do jogador e decide o que fazer quando qualquer dado for alterado.


Agora expanda o Playercontroller para que possamos interagir com os dados


PlayerPresenter.cs


 public class PlayerPresenter { private PlayerView _playerView; private PlayerModel _playerModel public PlayerPresenter(PlayerView view, PlayerModel model) { _playerView = view; _playerModel = model; } public void Enable() { _playerModel.Death += Death; _playerModel.ChangedHealth += ChangeHealth; } private void ChangeHealth(float health){ _playerView.Changehealth(health); } private void Death(){ _playerView.Death(); Disable(); } public void Disable() { _playerModel.Death -= Death; _playerModel.ChangedHealth -= ChangeHealth; } } 

Portanto, vamos expandir e o PlayerView


PlayerView.cs


 public class PlayerView : MonoBehaviour { public void Changehealth(float health) { //      //    slideBar   Text } public void Death() { //     } } 

Portanto, temos uma arquitetura extremamente conveniente para criar uma unidade (ou qualquer outro objeto), que pode ser expandida por qualquer mecânica. Precisa de mana? Ou movimento? Adicione mana flutuante, posição Vector3 ao modelo.


Qual deve ser a conclusão? Não interfira nos dados da exibição (MonoBehaviour) com erros de cálculo simples.
O apresentador, no nosso caso, está localizado acima do nível do PlayerView e PlayerModel e monitora se algo está mudando lá e responde a alterações. Ao mesmo tempo, o PlayerController também pode monitorar eventos de exibição, como colisões ou gatilhos.

Source: https://habr.com/ru/post/pt481618/


All Articles