LoginSignup
0
1

More than 1 year has passed since last update.

【Unity】MVRPパターンを使用してHPゲージを作ってみた

Posted at

はじめに

UniRxを書くようになって、UniRxと相性の良いMVRP(Model-View-Reactive-Presenter)パターンがあるというのは耳にしていたのですが、今回初めて自分で書いてみたので記録として残しておきます。

環境

OS : Windows10
Unity バージョン : 2021.3.2f1

HPゲージの作成

  1. プレイヤーの頭上に追従するHPゲージを実装したかったため、プレイヤーの子にCanvasを用意します。
  2. SliderをCanvasの子に作成し、Handle Slide Areaは今回使用しないため削除します。

image.png

コンポーネントの作成

今回作成したコンポーネントは以下3つになります。

  • HPModel
  • HPView
  • HPPresenter

HPModel

HPModelでは、ReactivePropertyを使用し、HPを公開しているのみです。

HPModel.cs
using UnityEngine;
using UniRx;

public class HPModel: MonoBehaviour
{
    /// <summary>
    /// 最大HP
    /// </summary>
    public readonly int maxHP = 100;

    /// <summary>
    /// 残っているHP
    /// </summary>
    public IReadOnlyReactiveProperty<int> HP => _hp;

    private readonly IntReactiveProperty _hp = new IntReactiveProperty();

    private void Start()
    {
        _hp.Value = maxHP;
    }
    /// <summary>
    /// ダメージを受けたときの処理
    /// </summary>
    public void GetDamage()
	{
        _hp.Value -= 10;
	}

	private void OnDestroy()
	{
        _hp.Dispose();
	}
}

HPView

HPViewでは、Sliderを変化させるのみです。

HPView.cs
using UnityEngine;
using UnityEngine.UI;

public class HPView : MonoBehaviour
{
    /// <summary>
    /// HPゲージ
    /// </summary>
    private Slider _hpGuage;

    private void Start()
    {
        _hpGuage = this.GetComponent<Slider>();
    }

    /// <summary>
    /// HPゲージの設定
    /// </summary>
    /// <param name="maxHP">最大HP</param>
    /// <param name="hp">残っているHP</param>
    public void SetGuage(int maxHP, float hp)
    {
        _hpGuage.value = hp / maxHP;
    }
}

HPPresenter

HPPresenterでは、HPModelとHPViewの橋渡しを行います。

HPPresenter.cs
using UnityEngine;
using UniRx;

public class HPPresenter : MonoBehaviour
{
    [SerializeField] private GameObject _player;
    private HPModel _hPModel;
    private HPView _hpView;
    private IGetHitEventProvider _getHitEventProvider;

    void Start()
    {
        _getHitEventProvider = _player.GetComponent<IGetHitEventProvider>();
        _hPModel = this.GetComponent<HPModel>();
        _hpView = this.GetComponent<HPView>();
        // 敵に当たった時の処理
        _getHitEventProvider.GetHit
            .Where(getHit => getHit == true)
            .Subscribe(_ => _hPModel.GetDamage());
        // HPModel内のHPが減ったことをViewへ知らせる
        _hPModel.HP
            .Subscribe(hp => _hpView.SetGuage(_hPModel.maxHP, hp)).AddTo(this);
    }
}

作成したコンポーネントをアタッチ

最初に作成したSliderにすべてのコンポーネントをアタッチします。
image.png
実際に動かすとこのようになりました。
ezgif-3-32c6f86455.gif

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1