Unity
UniRx

【Unity】UniRxを使って簡単にUIの画像をフワフワさせてみる

最近、仕事でもプライベートでもUniRxブームが自分の中で来ています。

今回はUniRxを使用してUIの画像をフワフワと上下に揺れるアニメーションを作成しました。

こちらはスプライトや3Dモデルでも、使う変数が違うくらいで考え方はほぼ一緒です


前提条件

UniRxをプロジェクトにインストール済み

Unity2018.2.21fでプロジェクトを作成


今回記載すること

・UniRxを用いた簡単な上下に繰り返し移動するアニメーション


記載しない(説明を省く)こと

・UniRxの基礎的な使い方

=>知りたい方はとりすーぷさんのUniRx入門シリーズ 目次を見てください。これ以上UniRx初心者で役立つ資料を僕は見たことがないです。

・Unityのスクリプト基礎

最低限、UpdateとかStartが何なのかをわかっている前提で記載しています。

わからなければ検索をかけてください。

・uGUIの基礎

最低限、ImageとCanvasぐらいは見たことがある前提で記載しています。


上下に揺らすために

スクリプトで上下に揺らすために調査したところ、

・Sin波(Mathf.Sin)を利用して毎フレーム計算する

・Mathf.PingPongを利用

で簡単に実現できそうです。

今回はSinを利用して上下に揺らしてみます。


単純にふわふわさせてみる

以下のようにスクリプトを組んでみます。


CharaImage.cs

using System;

using UnityEngine;
using UnityEngine.UI;
using UniRx;
using UniRx.Triggers;

/// <summary>
/// Chara image.
/// </summary>
public class CharaImage : MonoBehaviour
{
/// <summary>
/// Image
/// </summary>
[SerializeField]
private Image image = null;

/// <summary>
/// Start
/// </summary>
private void Start()
{
float imageY = image.rectTransform.anchoredPosition.y; // Yの初期値
float speed = 0.7f; // 移動スピード
float moveY = 15; // 移動値

// ふわふわ浮いてるようなアニメーション
this.UpdateAsObservable()
.Select(_ => image.rectTransform.anchoredPosition) // 画像のanchoredPositionを取得
.Subscribe(p =>
{
image.rectTransform.anchoredPosition = new Vector2(p.x, imageY + Mathf.Sin(Time.time * speed) * moveY);
});
}
}


上記スクリプトを揺らしたい画像があるコンポーネントにアタッチしてください。

※InspectorでSerializeFieldを指定したImageに、動かしたいImageをセットするのを忘れずに。

fuwafuwa.gif

※Gifがアップロード容量の問題でカットしていますが、ちゃんと上下に動きます

※購読停止処理をあえて抜いていますので、実際に使用する場合は以下のようにTakeUntilDestroy、Addto等でなにかしらの購読停止処理を必ず実装してください。

this.UpdateAsObservable()

.Select(_ => image.rectTransform.anchoredPosition)
.Subscribe(p =>
{
image.rectTransform.anchoredPosition = new Vector2(p.x, imageY + Mathf.Sin(Time.time * speed) * moveY);
})
.AddTo(this.gameObject);


クリックしたときに、ぴょこっとキャラを動かしてみる。

Imageをクリックしたときにぴょこっと動かしてみたいので、スクリプトに少し修正を加えます。

※EventTrigerをアタッチしてください

image.png


CharaImage.cs

using System;

using UnityEngine;
using UnityEngine.UI;
using UniRx;
using UniRx.Triggers;

/// <summary>
/// Chara image.
/// </summary>
public class CharaImage : MonoBehaviour
{
/// <summary>
/// Image
/// </summary>
[SerializeField]
private Image image = null;

/// <summary>
/// Start
/// </summary>
private void Start()
{
float imageY = image.rectTransform.anchoredPosition.y; // Yの初期値
float speed = 0.7f; // 移動スピード
float moveY = 15; // 移動値

// ふわふわ浮いてるようなアニメーション
this.UpdateAsObservable()
.Select(_ => image.rectTransform.anchoredPosition) // 画像のanchoredPositionを取得
.Subscribe(p =>
{
image.rectTransform.anchoredPosition = new Vector2(p.x, imageY + Mathf.Sin(Time.time * speed) * moveY);
});

// ObservablePointerClickTriggerをAddComponent
var clickTrigger = this.gameObject.AddComponent<ObservablePointerClickTrigger>();

// 画像をクリックしたときに、一定時間だけスピードを速くする
clickTrigger
.OnPointerClickAsObservable()
.ThrottleFirst(TimeSpan.FromSeconds(1)) // クリック後1秒間はスキップするように
.Select(_ => image.rectTransform.anchoredPosition)
.Subscribe(p =>
{
speed = 10;
moveY = 20;
// 画像の位置を初期値へ戻す
image.rectTransform.anchoredPosition = new Vector2(p.x, imageY);

// 500ミリ秒経過したら、初期値へ戻す
Observable
.Timer(TimeSpan.FromMilliseconds(500))
.Subscribe(_ =>
{
speed = 0.7f;
moveY = 15;
image.rectTransform.anchoredPosition = new Vector2(p.x, imageY);
});
})
}
}


こんな感じで、クリックするとぴょこっと動くようになりました。(かわいい)

fuwafuwa.gif

speedとmoveYの値をいい感じに調整して、理想のぴょこ動きを実装してみてください。


参考サイト

Sin波で上下に揺らす

unityのオブジェクトを上下に移動させる。