UniRx を試してみた
Unity でイベント処理などが複雑になってきたので、どうにかできないかと思い UniRx を試しました。
UniRx とは イベントを時系列に並んだシーケンスと捉え、それらを filter したり map したりすることでイベント処理を行うものです。
たとえば、Spaceキーが入力されたときに、プレイヤーをジャンプさせるといったことをする場合は、通常は以下のように Update()
でキーが入力されたか判定し、その結果のフラグをプロパティに保持しておき、FixedUpdate()
でフラグが立っていれば RidgedBody を操作するといったことをします。
using System; using UnityEngine; public class JumpBehaviourScript : MonoBehaviour { private Boolean isEnteredSpaceKey; private Rigidbody rigidBody; private void Start() { isEnteredSpaceKey = false; rigidBody = GetComponent<Rigidbody>(); } private void Update() { isEnteredSpaceKey = Input.GetKey(KeyCode.Space); } private void FixedUpdate() { if (isEnteredSpaceKey) { rigidBody.AddForce(Vector3.up, ForceMode.VelocityChange); } } }
この方法では、キーが押されたかの判定とその時の動作が別の場所にあるため、キー入力が多くなってくると見通しが悪くなってきます。
ここで、UniRx を用いると以下のように記述できます。
using UniRx; using UniRx.Triggers; using UnityEngine; public class JumpBehaviourScript : MonoBehaviour { private void Start() { var rididBody = GetComponent<Rigidbody>(); this.UpdateAsObservable() .Where(_ => Input.GetKey(KeyCode.Space)) .BatchFrame(0, FrameCountType.FixedUpdate) .Subscribe(_ => rididBody.AddForce(Vector3.up, ForceMode.VelocityChange)); } }
これは、 UpdateAsObservable()
で Update()
のタイミングでイベントが発生するというストリームを生成します。そして .Where(_ => Input.GetKey(KeyCode.Space))
でキーが押されたときだけ filter します。 そのあとに、 BatchFrame(0, FrameCountType.FixedUpdate)
でバッファにイベントをためておき、FixedUpdate()
のタイミングでポップします。最後に Subscribe(_ => rididBody.AddForce(Vector3.up, ForceMode.VelocityChange))
でジャンプする動作を行います。
このように、UniRx を用いることで、キー入力判定からジャンプの動作までを一つのストリームで簡潔に記述できます。
そのほかにも、MVPパターンのReactive実装のパターンである MV(R)P パターンの実装など Unity において様々なところで活躍しそうです。
UniRx については以下が詳しいです。
www.slideshare.net qiita.com
また、以下に調査時のサンプルコードがあります。