A Day In The Life

とあるプログラマの備忘録

UnityでRedux.NETを使ってみた

フロントエンド開発と iOS アプリ開発でステート管理に Redux(iOSはReSwift)を使っています。Unity でも Redux 使えないかなと探していたところ Redux.NET というC♯の実装を見つけたので使ってみることにしました。

手順

Redux.NET を使うためには Reactive Extensions というやつをインストールしないといけないのですが今のところ(2016年6月現在) Unity には対応していません。なので代わりに Reactive Extensions の Unity 実装である UniRx をインストールします。

UniRxのインストール

Asset Store からUniRxをインストールする

Redux.NETのインストール

Redux.NET は100行にも満たないシンプルなコードなのでインストールというほど大げさなものではないです。

GuillaumeSalles/redux.NET から Store.cs と IAction.cs をコピーして Unity プロジェクトの Scripts フォルダに追加してください。 github.com

Redux.NETをUnityで動くように修正する

Redux.NET はそのままではコンパイルエラーになるので以下のように Store.cs を修正します。

using System;
//using System.Reactive.Subjects;
using UniRx;

namespace Redux
{
    ...その他コード
}

以上で準備は完了です。

使い方

カウンターを使った簡単なサンプルを例に使い方をみてみましょう。

アクションの作成

初めにアクションを定義します。

public class IncrementAction : IAction { }

public class DecrementAction : IAction { }

ストアの作成

次にストアを定義します。

public class State
{
  public int Counter { get; set; }
}

Reducerの作成

最後に Reducer を作成します。

public static class CounterReducer
{
  public static State Execute(State state, IAction action)
  {
    if (action is IncrementAction)
    {
      return new State {
        Counter = state.Counter + 1
      }
    }
    else if (action is DecrementAction)
    {
      return new State {
        Counter = state.Counter - 1
      }
    }
    return state;
  }
}

ステートの監視

アクションの発行とステートを監視してみます。

using UnityEngine;
using UniRx;
using Redux;

public class Hoge : MonoBehaviour
{
  public IStore<State> Store { get; private set; }
  void Start()
  {
    // ストアの生成
    store = new Store<State>(Reducers.Hoge, initialState);
    store.Subscribe(state => {
      // stateが変わったら呼ばれる
      print(state.Counter);
    });
    // ボタンのイベント(ボタンが2つ配置されていると仮定)
    var buttons = GetComponentsInChildren<Button>();
    foreach (var button in buttons)
    {
      var name = button.name;
      button.onClick.AddListener(() => OnButtonClick(name));
    }
  }
  void OnButtonClick(string name)
  {
    if (name == "Increment")
    {
      // アクションの発行
      this.Store.Dispatch(new IncrementAction());
    }
    else if (name == "Decrement")
    {
      // アクションの発行
      this.Store.Dispatch(new DecrementAction());
    }
  }
}

注意点

一つだけ注意点があります。UniRx が iOS の Mono2x に対応していないため iOS アプリのビルドをする場合は IL2CPP に設定をしてから実行する必要があります。

おすすめUnity本