LoginSignup
4
3

[Unity] DOTweenとUniTaskでキャラクターのカットイン演出を作る

Last updated at Posted at 2023-12-22

はじめに

本記事はLife is Tech ! Advent Calendar 2023の22日目の記事です。

こんにちは!Life is Tech! でメンターをしているみったにです。
本記事では、DOTweenとUniTaskを使ってキャラクターのカットイン演出を作る方法を紹介します。

完成イメージ

Movie_021.gif

検証環境

Unity : 2022.3.9f1
UniTask : Ver.2.5.0
DOTween (HOTween v2)
Windows11

ライブラリについて

本記事で使用するUniTaskは、Unityの非同期処理を強力にサポートするライブラリです。
一方、DOTweenはUnityでのアニメーションとトゥイーン処理を手軽に扱うためのライブラリです。DOTweenを用いることで、位置やスケールの変更、色の遷移など、多様なアニメーションを簡単なコードで実現することができます。DOTweenは直接的には非同期処理を提供するわけではありませんが、その動作は非同期処理と類似しています。
そこにUniTaskを使用することで、DOTweenによるアニメーションの完了を非同期的に待つことが可能になります。

実装

1. ライブラリの導入

以下のURLからDOTweenとUniTaskを自分のUnityプロジェクトに入れておいてください。

DOTween

DOTweenのインストール方法は以下URLを参考にすると分かりやすいです。

UniTask

UniTaskのインストール方法は他のAssetとは少し勝手が違います。
Package Managerからインポートする手順はREADMEに記載があるので参考にしてください。

2. DOTweenでUniTaskを使えるようにする

DOTweenとUniTaskをプロジェクトにインポートしただけではDOTweenをUniTaskで使うことができません。

Edit > Project Settings... > Player > Other Settings > Script Compilation > Script Define Symbols に UNITASK_DOTWEEN_SUPPORT を入力してApplyを押します。

image.png

3. カットインのUIを作成する

まずはシーン上にCanvasを作成します。
UI Scale Mode を Scale With Screen Size に設定し、Reference Resolution を 1920×1080に設定してください。

image.png

次に、カットインのUIを作成します。
以下のような入れ子構造でUIの各パーツを制作しましょう。RectTransformの値は各個人の開発プロジェクトに合わせて作成してください。

image.png

CutInUI

CutInUIは CreateEmpty から作ると良いです。
Anchor Presetsは両方stretchを選択しましょう。

image.png

CutInMask

CutInMaskは UI > Image から作成すると良いです。
また、CutInMaskにはMaskコンポーネントを追加してください。こうすることで、CutInMaskの子要素の表示がCutInMaskのImageの範囲のみに限定されます。

image.png

CutInBackground

まずはCutInMaskの子オブジェクトではなく、同じ階層に UI > Image から作成しましょう。

image.png

今回は以下の画像のような1920px × 1080px のサイズの市松模様の画像を作成し、使用しました。

cutin_background.png

今回この市松模様の画像を傾けて使用したので、CutInBackgroundのRectTransformの設定が少しややこしくなっています。以下の画像のように、まずはRectTransformの値を設定してみましょう。

image.png

次に、Position Constraintコンポーネントを追加し、 Constraint Settings > Sources に先ほど作成したCutInUIを設定します。
こうすることで、CutInMaskをDOTweenでアニメーションさせても、CutInBackgroundはCutInUIの座標を追従するので、CutInBackgroundが動いていないように見えます。

image.png

Position Constraintの設定ができたら、CutInBackgroundをCutInMaskの子オブジェクトにしましょう。

image.png

CharacterImage

CharacterImageは、キャラクターの画像を設定します。
今回はユニティちゃんの画像を画面外右からカットインさせるので、以下のように設定しています。

image.png

ここまでカットインのUIを設定すれば、Scene上では以下の画像のようになります。

image.png

4. カットインアニメーションのコードの実装

実際にDOTweenとUniTaskを用いてコードを書いていきます。

CutInAnimationView.cs
using System.Threading;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

public class CutInAnimationView : MonoBehaviour
{
    [SerializeField] private GameObject cutInUI;
    [SerializeField] private Image cutInCharacterImage;
    [SerializeField] private Image cutInBackgroundMask;

    public async UniTask StartCutIn(CancellationToken token)
    {
        var backgroundMaskRect = cutInBackgroundMask.GetComponent<RectTransform>();
        var characterRect = cutInCharacterImage.GetComponent<RectTransform>();
        cutInUI.SetActive(true);

        // 位置を初期化
        await UniTask.WhenAll(
            characterRect.DOAnchorPos(new Vector2(1600, -40), 0.0f).ToUniTask(cancellationToken: token),
            backgroundMaskRect.DOAnchorPos(new Vector2(300, 375), 0.0f).ToUniTask(cancellationToken: token),
            backgroundMaskRect.DOSizeDelta(new Vector2(0, 2500), 0.0f).ToUniTask(cancellationToken: token)
        );

        // カットインアニメーションの再生
        await UniTask.WhenAll(
            characterRect.DOAnchorPos(new Vector2(-400, -40), 0.5f).SetEase(Ease.OutCubic)
                .ToUniTask(cancellationToken: token),
            backgroundMaskRect.DOSizeDelta(new Vector2(2000, 2500), 0.5f).SetEase(Ease.OutCubic)
                .ToUniTask(cancellationToken: token)
        );

        // カットイン待機
        await UniTask.Delay(700, cancellationToken: token); // 700ミリ秒待機

        // カットインの終了アニメーションの再生
        await UniTask.WhenAll(
            characterRect.DOAnchorPos(new Vector2(-1500, -40), 0.3f).SetEase(Ease.InCubic)
                .ToUniTask(cancellationToken: token),
            backgroundMaskRect.DOAnchorPos(new Vector2(-1500, 375), 0.3f).SetEase(Ease.InCubic)
                .OnComplete(() => { cutInUI.SetActive(false); })
                .ToUniTask(cancellationToken: token)
        );
    }
}

このようにTweenをawaitするだけでDOTweenをasync/awaitすることができます。
また、ToUniTaskメソッドにCancellationTokenを渡すことで、キャンセル可能なasync/awaitのDOTweenを作成することができます。
また、UniTaskはDOTweenのキャンセル挙動も設定することができます。ここでは、OnCompleteを呼ぶことで、Tween終了時にCutInUIを非アクティブにしています。

詳しくは以下の記事で紹介されているので、参考にしてください。

5. カットインを再生するコードの実装

カットインを再生するスクリプトも作成しましょう。

CutInAnimationPresenter.cs
using System.Threading;
using UnityEngine;

public class CutInAnimationPresenter : MonoBehaviour
{
    [SerializeField] private CutInAnimationView view;

    private async void Start()
    {
        // CancellationTokenSourceを作成
        var cts = new CancellationTokenSource(); 
        // CancellationTokenを取得 
        var token = cts.Token;                      

        await view.StartCutIn(token);

        cts.Cancel();
    }
}

CancellationTokenSourceを作成し、CancellationTokenを取得します。そしてそのCancellationTokenをCutInAnimationViewのToUniTaskメソッドでTweenにTokenを渡します。

確認

シーン上に空のゲームオブジェクトを作成し、先ほど作成したCutInAnimationViewとCutInAnimationPresenterをアタッチしましょう。
アタッチしたら、Inspector Viewに各ゲームオブジェクトなどを設定します。
image.png

アタッチができたら、実際に再生してカットインを確認しましょう。

動作確認

Movie_021.gif

さいごに

いかがだったでしょうか?

本記事では、DOTweenとUniTaskでUIをアニメーションさせる方法の一例を紹介しました。
UIのアニメーションはDOTweenだけではなく、UnityのTimelineなども用いられて実装される場合もあるので、あくまでも一例として見ていただければ幸いです。
また、DOTweenとUniTaskは今回紹介したもの以外も様々な機能があり、それを駆使すればリッチな表現が可能になります。
本記事を見て少しでもDOTweenとUniTaskについて参考にしていただけたらと思います。

さて、明日のLife is Tech ! Advent Calendar 2023は @zawanume の記事になります。
どうやらMinecraftに関する記事のようです。自分もMinecraftは普段から遊んだり、MOD開発などをしているのでとても楽しみです!

以上、Life is Tech! メンターのみったにでした。

参考記事

© Unity Technologies Japan/UCL

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3