Kiến trúc: Mẫu Model-View-Presenter (MVP)
C# Code
using UnityEngine;
using UnityEngine.UI;
// 1. Model: Chứa dữ liệu và logic cốt lõi, không biết gì về UI.
public class PlayerStatsModel
{
public int Health { get; private set; }
public int MaxHealth { get; private set; }
public event System.Action OnHealthChanged;
public PlayerStatsModel(int initialHealth) {
MaxHealth = initialHealth;
Health = initialHealth;
}
public void TakeDamage(int amount) {
Health = Mathf.Max(0, Health - amount);
OnHealthChanged?.Invoke();
}
}
// 2. View: Chỉ chịu trách nhiệm hiển thị và nhận input từ người dùng.
public interface IHealthView
{
void UpdateHealth(int currentHealth, int maxHealth);
event System.Action OnHealButtonClicked;
}
public class HealthView : MonoBehaviour, IHealthView
{
public Slider healthSlider;
public Text healthText;
public Button healButton;
public event System.Action OnHealButtonClicked;
void Awake() {
healButton.onClick.AddListener(() => OnHealButtonClicked?.Invoke());
}
public void UpdateHealth(int current, int max) {
healthSlider.value = (float)current / max;
healthText.text = $"{current} / {max}";
}
}
// 3. Presenter: Lắng nghe input từ View, cập nhật Model, và ra lệnh cho View hiển thị.
public class HealthPresenter
{
private PlayerStatsModel _model;
private IHealthView _view;
public HealthPresenter(PlayerStatsModel model, IHealthView view) {
_model = model;
_view = view;
// Đăng ký lắng nghe sự kiện từ cả Model và View
_model.OnHealthChanged += OnModelHealthChanged;
_view.OnHealButtonClicked += OnViewHealRequest;
// Cập nhật View lần đầu
OnModelHealthChanged();
}
private void OnModelHealthChanged() {
_view.UpdateHealth(_model.Health, _model.MaxHealth);
}
private void OnViewHealRequest() {
// Người dùng nhấn nút Heal, Presenter ra lệnh cho Model
_model.TakeDamage(-10); // Hồi 10 máu
}
}
// 4. Khởi tạo trong một Bootstrap hoặc Manager class
public class GameBootstrap : MonoBehaviour {
public HealthView view;
void Start() {
var model = new PlayerStatsModel(100);
var presenter = new HealthPresenter(model, view);
// Để test, thử gây sát thương cho model
model.TakeDamage(20);
}
}Áp dụng mẫu MVP để tách biệt logic game (Model), UI (View), và phần điều khiển trung gian (Presenter). Giúp code dễ dàng unit test và quản lý các luồng dữ liệu phức tạp trong UI.