MVP가 생각보다 어려워서 두번째 예제를 만듬
Monster가 죽으면 싱글톤 MonsterManager에서 MonsterDead라는 이벤트를 Invoke한다.
Gold변화량을 UI에 표시해야할때 아래처럼 사용.
Inspector에서는 Player의 데이터와 Present이므로 이렇게 Player 스크립트 폴더 안에다가 구성했다.
GameObject에 컴포넌트 넣는 부분은 없음. Present와 Model은 Monobehavior가 없는 class 파일이므로 new로 생성 해주면된다

public class PlayerModel
{
//플레이어가 가지고있는 골드와 추가하는 메서드 기능 정의
public int Gold { get; private set; } = 0;
public void AddGold(int amount)
{
Gold += amount;
}
}
public interface IPlayerMVPView
{
//UI에서 정의되어야할, 처리할 기능
public void UpdateGoldValue(int goldValue);
}
public class PlayerMVPPresenter
{
//Model과 View를 private 필드로 가지고있는다
private PlayerModel _model;
private IPlayerMVPView _playerView;
//생성자로 값을 넣어줌 (이 케이스는 싱글톤에서 Model을 가져옴)
public PlayerMVPPresenter(IPlayerMVPView view)
{
//골드는 Player의 정보이므로 PlayerManager라는 싱글톤에서 가져왔다
_model = PlayerManager.Instance.Model;
_playerView = view;
//몬스터가 사망했을때 골드가 변화하므로 이벤트 구독
MonsterManager.Instance.monsterDead += OnMonsterDead;
}
//몬스터 사망 시 돈이 오름
private void OnMonsterDead(int reward)
{
_model.AddGold(reward);
//View에서 정의될 메서드에 정보를 넣어준다
_playerView.UpdateGoldValue(_model.Gold);
}
//해당 Present가 정의된곳에 Dispose로 이벤트 해지 등 하도록
public void Dispose()
{
MonsterManager.Instance.monsterDead -= OnMonsterDead;
}
}
public class UIManager : Singleton<UIManager>, IPlayerMVPView
{
//텍스트 UI 지정
[SerializeField] TextMeshProUGUI goldText;
//Present 지정
private PlayerMVPPresenter _presenter;
//별건아니고 싱글톤이라서 Awke할때 1개만 존재하도록 부모에 정의되어있다
protected override void Awake()
{
base.Awake();
}
//_presenter를 만들어줘서 동작하도록 한다
private void Start()
{
goldText.text = "Gold!!";
_presenter = new PlayerMVPPresenter(this);
}
//인터페이스 메서드를 구현해서 해당값으로 UI텍스트 변화하도록
public void UpdateGoldValue(int goldValue)
{
goldText.text = "Gold: " + goldValue.ToString();
}
}
public class PlayerManager : Singleton<PlayerManager>
{
[SerializeField] private Player _player;
public Player _Player => _player;
//플레이어 모델 필드로 추가(어디서든 가져올수있게 싱글톤에 public으로)
public PlayerModel Model { get; private set; }
protected override void Awake()
{
base.Awake();
//new로 초기 생성
Model = new PlayerModel();
}
//아래는 그냥 싱글톤에서 Player가 Start되면 스스로 Set하는 코드 (MVP코드는 아니다)
public void SetPlayer(Player player)
{
_player = player;
}
}