@Baiteen
ReactiveExtensionsがUnityでも使えるってのを今更知ったので、今更ながら使ってみた。その7。
やりたいこと
ReactiveExtensionsを使ってクリック回数をトースト表示しつつ、左右にあるCubeオブジェクトを動かす。せっかくなので、左のCubeはRigitbodyにAddForceで、右のCubeはイベント経由で動かすようにした。
前回の記事が分かりづらいと評判だったので、前回の補足も兼ねて。
やったこと
(UniRxはインポート済み)※前回からUnityのバージョンが 4.6 beta になってます。(uGUIを使ってみたかっただけ)
前回のなごりでPlaneを追加(Planeじゃなくてもいい)
暗いのでDirectional lightを追加
クリック用のSphereを追加
トースト表示するためのText追加(GameObject→UI→Text)。Textを追加すると勝手にCanvas、EventSystemも追加されるはず。
動かすためのCubeを2つ追加。左をBlueCube、右をRedCubeとしました。両方共にRigitbodyを追加。
Cubeに色を付けるためのMaterialを作成。BlueMaterialとRedMaterial。それぞれBlueCube,RedCubeにドラッグドロップでCubeに色がつくはず。
※Sphere、Cubeの位置は適当に調整してください。
C#Scriptを作成して名前をSphereScriptに変更
今回はもう一つC#Scriptを作成して名前をCubeScriptに変更
ここまででこんな感じになってるはず。
SphereScript、CubeScriptをそれぞれ以下のように変更
・SphereScript
using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UniRx; static class ColorExt { ////// Textのアルファ値をセットする拡張メソッド /// /// uGUIのText /// アルファ値 public static void setA (this UnityEngine.UI.Text text, float a) { text.color = new Color(text.color.r, text.color.g, text.color.b, a); } } public class SphereScript : ObservableMonoBehaviour { ///トースト表示用オブジェクト public GameObject Toast; ///赤い四角オブジェクト public GameObject RedCube; ////// 指定秒間だけEveryUpdateを発行する /// ////// 秒 private IObservable TakeSec (double value) { //0秒〜経過秒が値として発行される return Observable.EveryUpdate().Scan( new { time=0f, offset=Time.time } , (a, t)=>new { time=Time.time - a.offset, offset=a.offset } ).Select(delta => delta.time) .TakeUntil(Observable.Timer(System.TimeSpan.FromSeconds(value))); } #region 連打イベント関連 ここはC#のイベントの説明読んで public class BarrageEventArgs : EventArgs { public int ClickCount; public BarrageEventArgs(int clickCount){ this.ClickCount = clickCount; } } public event EventHandler Barrage; private void OnBarrage (BarrageEventArgs e) { if (Barrage != null) Barrage(this, e); } #endregion /// RXのサンプルがAwakeだったので、ここに書きました。 public override void Awake () { //参考サイト:http://neue.cc/2010/07/28_269.html //トースト用オブジェクトからuGUIのTextを取り出して、透明にする var text = Toast.GetComponent(); text.setA(0); //赤い四角オブジェクトからRigidbodyを取り出して、設定(重力無視&自然に止まって欲しいので空気抵抗を与える) var redRigidbody = RedCube.GetComponent (); redRigidbody.useGravity = false; redRigidbody.drag = 5; //nueuccさんのアドカレ記事をパクりました //クリック回数をトースト表示 OnMouseDownAsObservable () .Buffer (OnMouseDownAsObservable ().Throttle (System.TimeSpan.FromMilliseconds (250))) .Select (xs => xs.Count) //クリック回数をテキストにセット .Do(cnt => text.text = string.Format ("{0} clicks", cnt)) //クリック回数に比例した右向きの力を赤い四角に加える .Do(cnt => redRigidbody.AddForce(Vector3.right * cnt * 10)) //連打イベントを発生させる .Do(cnt => OnBarrage(new BarrageEventArgs(cnt))) .SelectMany(cnt => TakeSec(1).Do(t=>text.setA(t)).Last().SelectMany(_=>TakeSec(1).Do(t=>text.setA(1-t))) ) .Subscribe (t=>Debug.Log(t)); // If you use ObservableMonoBehaviour, must call base method ← サンプルにこう書いてますので、そのまま。 base.Awake (); } }
・CubeScript
using UnityEngine; using System.Collections; public class CubeScript : MonoBehaviour { // Use this for initialization void Start () { //自分からRigidbodyを取り出して、設定(重力無視&自然に止まって欲しいので空気抵抗を与える) var rigidbody = this.GetComponent(); rigidbody.useGravity = false; rigidbody.drag = 5; //Sphereを探し出して、SphereScriptを取り出して、連打イベントが発生したら自分に力を加える var sphereScript = GameObject.Find("Sphere").GetComponent (); sphereScript.Barrage += (sender, e) => { rigidbody.AddForce(Vector3.left * e.ClickCount * 10); }; } }
SphereScriptをSphereに、CubeScriptをBlueCubeにドラッグドロップ
Sphereに追加したSphereScriptに変数Toast、RedCubeがあるので、それぞれText、RedCubeをドラッグドロップ
これで完成。
Hosted by UnityRoom.com