Unity PR

【Unity】値が変更された際に処理を実行したい

記事内に商品プロモーションを含む場合があります

この記事では、値が変更された際に何かしらの処理を実行する方法を解説します。

プレイヤーや敵が回復、またはダメージをおった際やステートが変えられた場合など、値に変化があった時になにかしらの処理を加えたいなぁと思うことが多々あります。

実装方法は色々あるので1つずつ見てきましょう!

プロパティを使う

プロパティのSetter内に処理を書くことで簡単に値が変更された際の処理を実装できます。

public プロパティの型 プロパティ名 
{
    set
    {
        変数名 = value;
        // ここに処理を書く
    }
    get
    {
        return 変数名;                
    }
}

例えば、以下のコードはScoreが変更された際にログを出力します。

using UnityEngine;

public class Test : MonoBehaviour
{
    private int _score = 0;
    public int Score 
    { 
        get { return _score; } 
        set 
        { 
            _score = value;

            // 値が変更された際の処理
            Debug.Log(Score);
        }
    }

    void Update() 
    {
        // Spaceキーが押されたら
        if(Input.GetKeyUp(KeyCode.Space))
        {
            // スコアを増やす
            Score += 1;
        }
    }
}

updateで監視する

変更前の値をキャッシュしておき、update内で値が変更されているか監視し、変更された場合に処理を実行する方法です。

using UnityEngine;

public class Test : MonoBehaviour
{
    private int score = 0;

    // 変更前の値
    private int preScore;

    void Start() 
    {
        // 初期化
        preScore = score;
    }

    void Update() 
    {
        // Spaceキーが押されたら
        if(Input.GetKeyUp(KeyCode.Space))
        {
            // スコアを増やす
            score += 1;
        }

        if(preScore != score)
        {
            // ここに処理を書く(今回はscoreを出力)
            Debug.Log(score);

            // preScoreを更新
            preScore = score;
        }
    }
}

この方法はupdate内(高負荷)の処理を増やしてしまうため、あまりお勧めはできません。

UniRxを使う

無料アセットであるUniRxReactivePropertyを使うことで簡単に値が変更された際の処理を実装できます。

マイアセットに追加してない方は以下のリンクから追加してください。

LinkUniRx - Reactive Extensions for Unity,ツール/機能統合

追加したら Unityエディタ上部メニューのウィンドウパッケージマネージャー からUniRxを探してインポートしてください。

インポートできたら次にスクリプトを見ていきます。
ReactivePropertyは以下のように初期化します。

private ReactiveProperty<扱う型名> 変数名 = new ReactiveProperty<扱う型名>();

値にはValueを通してアクセスします。

変数名.Value

値が変更された際の処理を登録するにはSubscribeを使います。

変数名.Subscribe()

例えば、値が変更された際にその値をログで表示するには以下のようにします。

using UnityEngine;
using UniRx;  // usingを忘れずに

public class Test : MonoBehaviour
{
    private ReactiveProperty<int> score = new ReactiveProperty<int>();

    void Start() 
    {
        // 処理の登録
        score.Subscribe(value => Debug.Log(value));
    }

    void Update() 
    {
        // Spaceキーが押されたら
        if(Input.GetKeyUp(KeyCode.Space))
        {
            // スコアを増やす
            score.Value += 1;
        }
    }
}

ReactivePropertyはとても便利なので覚えておきましょう!