🚀

DOTween具体例備忘録

2024/12/01に公開

この記事は、神戸電子専門学校 ゲーム技研部 Advent Calendar 2024の1日目の記事です。
https://qiita.com/advent-calendar/2024/kdgamegiken

はじめに

Unityの DOTween という有名で便利なライブラリについての記事です。
導入や基本的な使い方は他の神様方が説明していただいてるので、この記事では組み合わせることでなんかそれっぽく見えるものを (自分が思い出せるように) 記事にまとめておきます。
今回は実装が楽かつ、すぐに効果が表れるようなものを載せています。
全てに共通することですが、引数の値とかは各自合ったものを使用してください。

浮遊物っぽい動き

ふわふわした動きです。舞台が宇宙とか、浮遊物があるような神秘的な空間なら背景オブジェクトとかに使えるかも。

FloatingObject
//============================
// 上下にふわふわ浮かぶ
//============================

// 引数は各自の物を
float v = UnityEngine.Random.Range(0.5f, 1.0f);
float d = UnityEngine.Random.Range(3.0f, 4.0f);
float delay = UnityEngine.Random.Range(0.0f, 1.0f);

transform.DOLocalMoveY(endValue: v, duration: d).
    SetRelative(true).
    SetLoops(loops: -1, loopType: LoopType.Yoyo).
    SetEase(ease: Ease.InOutSine). // InOut系がおすすめ 自然に上下する
    SetDelay(delay);  // 開幕他オブジェクトが同じ動きをする違和感解消


//============================
// 回転もするとそれっぽい
// (ここはわざわざDOTween使わなくてもいいかもね)
//============================

float rotateSpeed = 3.0f;
Vector3 rot = new Vector3(
    UnityEngine.Random.Range(-1.0f, 1.0f),
    UnityEngine.Random.Range(-1.0f, 1.0f),
    UnityEngine.Random.Range(-1.0f, 1.0f)
    );
rot *= rotateSpeed;

transform.DOLocalRotate(endValue: rot, duration: 1.0f).
    SetRelative(true).
    SetLoops(loops: -1, loopType: LoopType.Incremental).
    SetEase(ease: Ease.Linear); // Linearにしないと回転速度が不規則っぽくなって違和感
            

開始時点では同じような動きをしますが、durationをずらせば徐々にずれていくので開幕でこのオブジェクトを見る機会がない場合は大丈夫でしょう。
気になる場合は、Delayを使うと違和感が消えると思います。

UI:振動(Shake)編

UIの形にもよりますが、UIの値(HPとか)が変化したときにShakeするとなんかそれっぽいというのと、視覚的も動きがあることで変化したということをユーザーが無意識のうちに知りやすくなりますしいろいろお得。
Shakeというだけあって、衝撃を受けたときに使われることが多い。
例えば、敵からダメージを受けたときとか。

ゲージ+数値も表示してる系のUIとかなら、ゲージと数値は別々でShakeさせたほうがいいかも。

UIShakeAnimation
float d = 0.6f;
float s = 4;
transform.transform.DOShakePosition(duration: d, strength: s);

もし「揺れが足りない!」と感じたら第3引数のvibrateを設定してみてください。
デフォルトで10に設定されてるので、20とか30とかに。

余談ですが、例のHPゲージもDOTweenで作ってます。ゲージ動かすの+猶予ゲージもあとからついてくる感じの部分。

場合によってはShakeよりもJumpのほうが見栄えがいいこともあります。(ShakeのY軸にしか動かない版)
完全に好みではありますが。使い分けるのがいいですね。
自作ゲームでちょうどJump使ってる部分があったので載せておきます。

UI:拡縮編

「振動だと衝撃が強すぎるな・・・」というときは、拡縮がオススメ。
これも、視覚的にユーザーに情報を伝えやすいというのでオススメ。
何かの数字がカウントされていくだけの場合、振動だと表現がうるさすぎるので拡縮だけにするといい感じになったりする。コインの数とか。コンボがあるゲームならコンボ数表示に使うのがいいかも。

UIScaleAnimation
Vector3 beforeScale = new Vector3(1.2f, 1.2f, 1.2f); // 拡大時の大きさ
Vector3 afterScale = new Vector3(1.0f, 1.0f, 1.0f); // 元の大きさ
float d = 0.3f;

this.transform.localScale = beforeScale;
transform.DOScale(afterScale, d);

とあるゲームでは、ダメージ数によって振動と拡縮を分けていたりします。
小さいダメージの時は拡縮で、大ダメージの時は振動みたいな感じで。
うまく使い分けれるとGoodですね👍
試しにそれっぽいの作ってみました

UI:フロートイン

某プレゼンテーションソフトのアニメーションにある「フロートイン」っぽいな動きです。
(ゲームで使うにはちょっとあれなので、改変していますが)
使う場面としては、クリア時とか逆に失敗時のテキスト表示とかに使用できるかもしれません。

UIFloatIn
public class UIFloatIn : MonoBehaviour
{
    // 表示させる画像
    [SerializeField] private Image m_image;
    // 開始時と終了時の座標
    // endPosはstartPosより下に設定するのがおすすめ
    [SerializeField] private Vector2 m_startPos, m_endPos;

    private void Start()
    {
        // 開始時は透明度0
        Color prevColor = m_image.color;
        prevColor.a = 0.0f;
        m_image.color = prevColor;

        // 開始時の座標設定
        transform.localPosition = m_startPos;

        // 移動処理
        float moveDuration = 0.8f;
        transform.DOLocalMove(endValue: m_endPos, duration: moveDuration).
            SetEase(ease: Ease.OutElastic);  // ここ次第でいろんな動きになる

        // 移動が完了しきるより早く透明度は1にする
        float fadeDuration = 0.3f;
        m_image.DOFade(endValue: 1.0f, duration: fadeDuration);
    }
}

SetEaseに設定するイージング次第でいろんな動きになります。
(OutElasticとか、これ実装するまでどこで使うねんって思ってました)

今回はOutElasticにしていますが、OutBackとかでもいいかもしれません。


完全に某ソフトのを再現するならLinearとかになるのかな?(ゲームでは使う機会ないと思うが・・・分からん)。

おわり

すごく便利。
また簡単かついい感じの見つけたら更新します

お借りしたもの

DOTween
https://assetstore.unity.com/packages/tools/animation/dotween-hotween-v2-27676?locale=ja-JP&srsltid=AfmBOoohI6U830u7qZd5ba1mkyRvn1E3iG3KW2b2kMdV-SFc-ojmKCgu

イージング関数グラフ画像お借りしました
https://easings.net/ja

神戸電子専門学校ゲーム技術研究部

Discussion