@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


