【Unity】アイテム出現のアニメーション効果を実装

アイテムが出現するときにアニメーション効果つきで実行される方法についてみていきましょう

実行結果

スペースキーを押下すると、特定の位置まで大きさを0から最初の大きさまで変化させながら移動し、大きさをバウンドさせながら停止します

基本コード

実行用コード(空のゲームオブジェクトにアタッチされます)

オブジェクトを作成(ジェネレート)して、そのオブジェクトにアタッチされているスクリプトのメソッドを実行するコード

変数一覧

obj作成したいオブジェクトの下になるPrefab
AnimationObjectScriptobjにアタッチされているスクリプト(クラス)
MoveAndBounceAnimationObjectScriptクラスのメソッド

コード

using UnityEngine;

public class MoveAndBounceTest : MonoBehaviour
{
    [SerializeField]
    GameObject obj;
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            GameObject createObj = Instantiate(obj);
            createObj.GetComponent<AnimationObjectScript>().MoveAndBounce();
        }
    }
}

オブジェクトをアニメーションするためのコード(Prefabにアタッチされます)

using DG.Tweening;
using UnityEngine;

public class AnimationObjectScript : MonoBehaviour
{
    public void MoveAndBounce()
    {
        // オブジェクトから Collider コンポーネントを取得し、それを colliderCache という変数に格納します
        var colliderCache = GetComponent<Collider>();

        // colliderCache が格納する Collider コンポーネントの有効/無効を切り替えます
        // これにより、当該オブジェクトの衝突判定が無効になります
        colliderCache.enabled = false;

        // オブジェクトの Transform コンポーネントを取得し、それを transformCache という変数に格納します
        // transform はオブジェクトの位置、回転、スケールなどの情報を管理するためのコンポーネントです
        var transformCache = transform;

        // オブジェクトのローカル座標 (transform.localPosition) にランダムな位置のベクトルを加え、
        // dropPosition という変数に格納します。これにより、オブジェクトの位置がランダムに変更されます
        var dropPosition = transform.localPosition + new Vector3(Random.Range(-10f, 10f), 0, Random.Range(-10f, 10f));

        // transformCache の位置を dropPosition に指定された時間 (2秒) かけてTweenアニメーションを使用して変更します
        // オブジェクトはランダムな位置に移動します
        transformCache.DOLocalMove(dropPosition, 2f);

        // オブジェクトの現在のスケール(localScale) を defaultScale という変数に格納します
        var defaultScale = transformCache.localScale;

        // オブジェクトのスケールをゼロに設定し、オブジェクトを非表示にします
        transformCache.localScale = Vector3.zero;

        // transformCache のスケールを元のスケール (defaultScale) にTweenアニメーションを使用して変更します
        transformCache.DOScale(defaultScale, 2f)

            // SetEase メソッドを使用して、アニメーションのイージング(ここでは「Ease.OutBounce」)を指定します
            // これにより、オブジェクトは元のサイズに戻りつつ、バウンド効果が加わります
            .SetEase(Ease.OutBounce)

            // アニメーションが完了した際に、colliderCache の有効状態を再び有効にし、
            // オブジェクトの衝突判定を有効にします。これにより、オブジェクトが元の位置・サイズに戻った後、
            // 再び衝突判定が有効になります
            .OnComplete(() =>
            {
                colliderCache.enabled = true;
            });
    }
}

学習のための基本テスト

シーン構成

CubeのPrefabを作成して、スクリプトをアタッチします

ジェネレーション用(オブジェクトを作成)のテストコードを実行するための空のオブジェクトを作成します

テストコード

objの型をGameObjectからAnimationObjectScript変更して、ここに代入するのは、すでにGetComponentで取得されたスクリプトになるようにしています
これにより、直接、MoveAndBounceメソッドを呼び出せるようになります

using UnityEngine;

public class MoveAndBounceTest : MonoBehaviour
{
    [SerializeField]
    AnimationObjectScript obj;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            AnimationObjectScript createObj = Instantiate(obj);
            createObj.MoveAndBounce();
        }
    }
}

MoveAndBounceメソッドを読み取ると何をしているのかがわかるようにリファクタリングしています
このリファクタリングでは、以下の点を考慮し、コードをより読みやすく、メンテナンスしやすくします

  1. 変数とメソッドの名前をわかりやすくし、コードの理解を助ける
  2. コードの重複を削減し、コンポーネントの再取得を回避する
  3. コメントの修正や削除を行い、コード自体が説明的であるようにする
using DG.Tweening;
using UnityEngine;

public class AnimationObjectScript : MonoBehaviour
{
    private Collider cachedCollider;
    private Transform cachedTransform;

    private void Start()
    {
        CacheComponents();
    }

    public void MoveAndBounce()
    {
        DisableCollider();
        Vector3 targetPosition = GetRandomizedPosition();
        MoveWithAnimation(targetPosition);
        ScaleWithAnimation();
    }

    private void CacheComponents()
    {
        cachedTransform = transform;
        cachedCollider = GetComponent<Collider>();
    }

    private void DisableCollider()
    {
        cachedCollider.enabled = false;
    }

    private void EnableCollider()
    {
        cachedCollider.enabled = true;
    }

    private void MoveWithAnimation(Vector3 targetPosition)
    {
        cachedTransform.DOLocalMove(targetPosition, 2f);
    }

    private void ScaleWithAnimation()
    {
        Vector3 defaultScale = cachedTransform.localScale;
        cachedTransform.localScale = Vector3.zero;
        cachedTransform.DOScale(defaultScale, 2f)
            .SetEase(Ease.OutBounce)
            .OnComplete(CompleteAnimation);
    }

    private void CompleteAnimation()
    {
        EnableCollider();
    }

    private Vector3 GetRandomizedPosition()
    {
        return cachedTransform.localPosition + new Vector3(Random.Range(-10f, 10f), 0, Random.Range(-10f, 10f));
    }
}

参考

コメント付き

using DG.Tweening;
using UnityEngine;

public class AnimationObjectScript : MonoBehaviour
{
    Collider colliderCache;
    Transform transformCache;

    public void MoveAndBounce()
    {
        // コンポーネントを取得して、変数に代入します(何回もGetComponentメソッドを実行しなくても良くします)
        CashComponent();

        // アニメーションの最中はコライダーを無効にして、取られないようにします
        EnabeCollider(false);

        // アニメーションしてどの位置に移動するかをランダムに決めます
        Vector3 dropPosition = GetMovedEndPosition();

        // 決めた位置に向かってアニメーションしながら移動します
        MoveEase(dropPosition);

        // 次に大きさの変更アニメーションを実行します
        ScaleEase();
    }

    private void ScaleEase()
    {
        // オブジェクトの現在の大きさ(localScale) を defaultScale という変数に格納します
        var defaultScale = transformCache.localScale;

        // スケールアニメーションを大きさ0から始めます
        transformCache.localScale = Vector3.zero;

        // transformCache のスケールを元のスケール (defaultScale) にTweenアニメーションを使用して変更します
        transformCache.DOScale(defaultScale, 2f)

            // SetEase メソッドを使用して、アニメーションのイージング(ここでは「Ease.OutBounce」)を指定します
            // これにより、オブジェクトは元のサイズに戻りつつ、バウンド効果が加わります
            .SetEase(Ease.OutBounce)

            // アニメーションが全て完了した際に実行されるコールバックメソッドです
            .OnComplete(CompleteAnimation);
    }

    void CompleteAnimation()
    {
        // アニメーションが完了した際に、colliderCache の有効状態を再び有効にし、
        // オブジェクトの衝突判定を有効にします。これにより、オブジェクトが元の位置・サイズに戻った後、
        // 再び衝突判定が有効になります
        EnabeCollider(true);
    }
    private void MoveEase(Vector3 dropPosition)
    {

        // transformCache の位置を dropPosition に指定された時間 (2秒) かけてTweenアニメーションを使用して変更します
        // オブジェクトはランダムな位置に移動します
        transformCache.DOLocalMove(dropPosition, 2f);
    }

    private Vector3 GetMovedEndPosition()
    {
        // オブジェクトのローカル座標 (transform.localPosition) にランダムな位置のベクトルを加え、
        // dropPosition という変数に格納します。これにより、オブジェクトの位置がランダムに変更されます
        return transform.localPosition + new Vector3(Random.Range(-10f, 10f), 0, Random.Range(-10f, 10f));
    }

    private void CashComponent()
    {
        // オブジェクトの Transform コンポーネントを取得し、それを transformCache という変数に格納します
        // transform はオブジェクトの位置、回転、スケールなどの情報を管理するためのコンポーネントです
        transformCache = transform;

        // オブジェクトから Collider コンポーネントを取得し、それを colliderCache という変数に格納します
        colliderCache = GetComponent<Collider>();
    }

    private void EnabeCollider(bool isEnable)
    {
        // colliderCache が格納する Collider コンポーネントの有効/無効を切り替えます
        // false(無効)の場合、このオブジェクトの衝突判定が無効になります
        colliderCache.enabled = isEnable;
    }
}

TWeen,Unity

Posted by hidepon