Static / Dynamic / Popup
A. Render 방식 변화에 따른 최적화가 이루어짐
Unity6 에서는 기본으로 사용

게임 Logic 은 건들지 않고 UI 만 갈아 끼우는 설계
참고: MVP(Model-View-Presenter) 패턴도 있음.
using TMPro;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public int hp = 100;
public TextMeshProUGUI hpText;
public void OnDamage(int damage)
{
hp -= damage;
hpText.text = "HP: " + hp.ToString();
}
}
👉A. 유지보수의 지옥

// PlayerModel.cs
public class PlayerModel
{
public int Hp = 100;
}
// PlayerView.cs
using UnityEngine;
using UnityEngine.UI;
public class PlayerView : MonoBehaviour
{
public PlayerModel playerModel;
public Slider hpSlider;
public void UpdateView()
{
hpSlider.value = playerModel.Hp / 100f;
}
}
// PlayerController.cs
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public PlayerModel playerModel = new();
public PlayerView playerView;
public void OnDamage(int damage)
{
playerModel.Hp -= damage;
playerView.UpdateView();
}
}
// PlayerModel.cs
public class PlayerModel
{
public int Hp = 100;
}
// PlayerView.cs
using UnityEngine;
using UnityEngine.UI;
public class PlayerView : MonoBehaviour
{
public Slider hpSlider;
public void SetFillAmount(float ratio)
{
hpSlider.value = ratio;
}
}
// PlayerPresenter.cs
using UnityEngine;
public class PlayerPresenter : MonoBehaviour
{
public PlayerModel playerModel = new();
public PlayerView playerView;
public void TakeDamage(int damage)
{
playerModel.Hp -= damage;
float ratio = playerModel.hp / 100f;
playerView.SetFillAmount(ratio);
}
}
StatusModel.cspublic class StatusModel
{
public float Hp;
public float MaxHp;
public float GetRatio() => Hp / MaxHp;
}
StatusView.csusing TMPro;
using UnityEngine;
using UnityEngine.UI;
public class StatusView : MonoBehaviour
{
[SerializeField] private Slider _slider;
public void SetValue(float ratio) => _slider.value = ratio;
}
public class TextPercentView : MonoBehaviour
{
public TMP_Text _text;
public void SetProgress(float ratio) => _text.text = $"{ratio}%";
}
StatusPresenter.csusing UnityEngine;
public class StatusPresenter : MonoBehaviour
{
private StatusModel _statusModel = new ();
[SerializeField] private StatusView _statusView;
[SerializeField] private TextPercentView _textView;
public void TakeDamage(float damage)
{
_statusModel.Hp -= damage;
_statusView.SetValue(_statusModel.GetRatio());
_textView.SetProgress(_statusModel.GetRatio());
}
}
ScoreModel.cspublic class ScoreModel
{
private int score;
public event System.Action<int> OnScoreChange;
public void AddScore(int amount)
{
score += amount;
OnScoreChange?.Invoke(amount);
}
}
ScoreViews.csusing UnityEngine;
public class ScoreView : MonoBehaviour
{
public void UpdateScore(int score)
{
// ToDo: Do something
}
}
public class TargetView : MonoBehaviour
{
public void UpdateScore(int score)
{
// ToDo: Do something
}
}
public class RankingView : MonoBehaviour
{
public void UpdateScore(int score)
{
// ToDo: Do something
}
}
ScorePresenter.csusing UnityEngine;
public class ScorePresenter : MonoBehaviour
{
[SerializeField] private ScoreView _scoreView;
[SerializeField] private TargetView _targetView;
[SerializeField] private RankingView _rankingView;
[SerializeField] private PopUpView _popUpView;
private ScoreModel _scoreModel = new();
private void OnEnable()
{
_scoreModel.OnScoreChange += _scoreView.UpdateScore;
_scoreModel.OnScoreChange += _targetView.UpdateScore;
_scoreModel.OnScoreChange += _rankingView.UpdateScore;
_scoreModel.OnScoreChange += CheckAchivement;
}
private void OnDisable()
{
_scoreModel.OnScoreChange -= _scoreView.UpdateScore;
_scoreModel.OnScoreChange -= _targetView.UpdateScore;
_scoreModel.OnScoreChange -= _rankingView.UpdateScore;
_scoreModel.OnScoreChange -= CheckAchivement;
}
private void CheckAchivement(int score)
{
if (score > 100)
{
_popUpView.Show(score.ToString());
}
}
}
❓: UI 뿐만 아니라 다른 기능들도 MVP 로 연결하는 것이 보통인가? 혹은 외적으로 보이는 기능 외 게임 내 기능끼리와의 연결도 MVP 로 하는 것이 보통인가?
(게임 규모에 따라 다르겠지만)
👉: 클라이언트 게임 개발에서는 View 는 대부분 UI 에 해당하기 때문에 다른 기능이나 클래스등과의 연결을 MVP 로 하는 경우는 흔치 않다. 다만, 응용하여 적용하거나 하는 것은 개발자 개인의 역량에 따를 것 같다.
❓: 보통 게임 개발에서 데이터 모델링의 주체는 "개발자"일 것 같은데, 모델링을 위해서는 데이터 지표가 제대로 나와야 한다. 그것은 기획의 영역에 가까운가?
👉: 개발 전 데이터에 대한 개념이나 정의 등은 기획에서 넘어오는 경우가 많지만, 상세 부분은 개발자의 역량이 적용되는 부분이 있다. 그리고 이 또한 규모에 따라도 다를 것 같다.