またまたありがちな例ですがUniRxとUnityに慣れるために書いてみました。
UniRx版
using UnityEngine; using System.Collections; using UniRx; public class UniRxRollingBehaviour : ObservableMonoBehaviour { public override void 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; public class NormalRollingBehaviour : MonoBehaviour { private bool drag; private bool first = true; private Vector3 prevPosition; // Update is called once per frame void 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; } } }