またまたありがちな例ですがUniRxとUnityに慣れるために書いてみました。
UniRx版
using UnityEngine; using System.Collections; using UniRx; publicclass UniRxRollingBehaviour : ObservableMonoBehaviour { publicoverridevoid Awake() { var drag = this.UpdateAsObservable() .Where(_ => Input.GetMouseButton(0)) .SkipUntil(this.UpdateAsObservable() .Where(_ => Input.GetMouseButtonDown(0)) .Select(_ => { RaycastHit rh; return Tuple.Create(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out rh), rh); }) .Where(x => x.Item1 && x.Item2.collider.gameObject == this.gameObject)) .TakeUntil(this.UpdateAsObservable().Where(_ => Input.GetMouseButtonUp(0))) .Repeat() .Select(_ => Input.mousePosition); drag.Zip(drag.Skip(1), (x, y) => Tuple.Create(x, y)) .Select(x => x.Item2 - x.Item1) .Select(x => new Vector3(x.y, -x.x, x.z)) .Subscribe(x => this.transform.Rotate(x)); base.Awake(); } }
今回はがっつり1ステートメントに詰め込みました。そのぶん短くなったかな。コメントがあれば個人的には許容範囲かも。
続いて比較のためにUniRx無い版を書いてみた。状態管理のためのフラグとかが増えてきてちょっといやな感じを醸し出しはじめてるけど、まだ許容範囲。
using UnityEngine; using System.Collections; publicclass NormalRollingBehaviour : MonoBehaviour { privatebool drag; privatebool first = true; private Vector3 prevPosition; // Update is called once per framevoid Update() { print("update"); // ドラッグ中じゃなくてマウスが押されたらif (!drag && Input.GetMouseButtonDown(0)) { // 対象オブジェクトの上でクリックされたかチェックして RaycastHit rh; if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out rh)) { if (rh.collider.gameObject == this.gameObject) { // 対象オブジェクトの場合は、ドラッグ中の状態にする drag = true; } } } // ドラッグ中にマウスが離されたらドラッグ中を解除して処理を抜けるif (drag && Input.GetMouseButtonUp(0)) { drag = false; return; } // ドラッグ中はif (drag) { print("drag"); if (!first) { var diff = Input.mousePosition - prevPosition; print(diff); this.transform.Rotate(new Vector3(diff.y, -diff.x, diff.z)); } first = false; prevPosition = Input.mousePosition; } } }