フェードを有効にしてモーションをループ再生させる (CubismMotionController)

最終更新: 2024年11月28日

概要

Cubism Viewer for OWでモーションをループ再生する際、「ループ再生時のフェードイン」にチェックが入っていた場合、モーションが終端から先頭に戻る際にCubismのモーションフェード、パラメータフェードが発生します。
フェードの設定についての詳細は、Editorマニュアルの「モーションの設定」をご覧ください。

しかし、Cubism SDK for UnityのCubismMotionController.PlayAnimation()の引数 isLoop にtrueを渡してモーションをループ再生する場合、終端から先頭に戻る際にフェードは発生しません。

CubismMotionControllerに存在するモーション再生終了時に呼び出されるコールバックを利用し、コールバックから同じモーションを新たに再生させることでフェードを発生させてモーションをループさせることができます。

上記の設定をするには、一例として以下のような手順を行います。

  • モデルにCubisMotionControllerをアタッチ
  • ループ再生処理を行うスクリプトを作成

以下では「SDKのインポート」をおこなったプロジェクトに対して行うことを前提として説明します。

モデルにCubisMotionControllerをアタッチ

Sceneに配置したCubismのPrefabのルートとなるGameObjectに、CubismMotionControllerをアタッチします。

既にアタッチされていれば新たにアタッチする必要がありません。
その際、CubismMotionControllerを使用してモーションを再生するコンポーネントがアタッチされている場合、以下の設定との干渉に注意してください。

また、CubismFadeController.CubismFadeMotionに、ループ再生させるAnimationClipのIDが登録された.fadeMotionListを設定します。

ループ再生処理を行うスクリプトを作成

ProjectウィンドウでC#スクリプトを作成します。

ここでは名前を「CubismMotionLoopPlayer」とします。

作成したスクリプトを、PrefabのCubismMotionControllerと同階層にアタッチします。

作成したスクリプトをテキストエディタで開き、記述内容を以下のように書き換えます。

using UnityEngine;
using Live2D.Cubism.Framework.Motion;

public class CubismMotionLoopPlayer : MonoBehaviour
{
    // ループ再生させるAnimationClip
    [SerializeField]
    public AnimationClip Animation;

    private CubismMotionController _motionController;


    private void Start()
    {
        _motionController = GetComponent<CubismMotionController>();
        
        
        // モーションをループ再生
        _motionController.PlayAnimation(Animation);
    }
}

Scene上のPrefabを選択状態にして、InspectorウィンドウからCubismMotionLoopPlayer.Animationにループ再生させるAnimationClipを設定します。

以上の設定をした状態でシーンを再生するとモーションがループ再生されますが、ループ時にフェードが発生しません。

CubismMotionControllerにはモーション再生終了時に呼び出すコールバックを登録する機能が実装されています。

    public class CubismMotionController : MonoBehaviour
    {
        #region Action

        /// <summary>
        /// Action animation end handler.
        /// </summary>
        [SerializeField]
        public Action<float> AnimationEndHandler;

        /// <summary>
        /// Action OnAnimationEnd.
        /// </summary>
        private void OnAnimationEnd(int layerIndex, int instanceId)
        {
            _motionPriorities[layerIndex] = CubismMotionPriority.PriorityNone;

            if (AnimationEndHandler != null)
            {
                AnimationEndHandler(instanceId);
            }
        }

        #endregion
        
        ...

これを利用し、前述のCubismMotionLoopPlayerを直接ループ再生させず、モーション再生終了時に新たに同じモーションを再生するよう修正します。
CubismMotionController.PlayAnimation()のisLoopにtrueを渡している場合、CubismMotionController.AnimationEndHandlerのコールバックは呼び出されません。

using UnityEngine;
using Live2D.Cubism.Framework.Motion;

public class CubismMotionLoopPlayer : MonoBehaviour
{
    // ループ再生させるAnimationClip
    [SerializeField]
    public AnimationClip Animation;

    private CubismMotionController _motionController;


    private void Start()
    {
        _motionController = GetComponent<CubismMotionController>();
        
        
        // CubismMotionControllerのハンドラにコールバック関数を登録
        _motionController.AnimationEndHandler += OnAnimationEnded;
        
        
        // 初回のみ直接モーションを再生させる
        OnAnimationEnded(0);
    }


    // モーションが再生終了したときのコールバック
    private void OnAnimationEnded(int instanceId)
    {
        // モーション再生(ループ再生は無効)
        _motionController.PlayAnimation(Animation, isLoop:false);
    }
}

以上で設定は完了です。

この状態でシーンを再生すると、モーションがフェードしながらループ再生されます。

この記事はお役に立ちましたか?
はいいいえ
この記事に関するご意見・
ご要望をお聞かせください。