Enable Fade and Loop Motion (CubismMotionController)

Updated: 02/07/2020

Summary

When looping a motion in Cubism Viewer for OW, if “Fade-in during loop playback” is checked, Cubism motion fade and parameter fade will occur when the motion returns from the end to the beginning.
Reference: “Motion Settings

However, if the motion is played in a loop by passing true to the isLoop argument of CubismMotionController.PlayAnimation() in the Cubism SDK for Unity, no fade will occur when returning from the end to the beginning.

By using a callback that is called when motion playback ends, which exists in the CubismMotionController, the same motion can be played again from the callback to generate a fade and loop the motion.

To set up the above, follow the steps below as an example.

  • Attach CubismMotionController to the model
  • Create a script to perform loop playback processing

The following explanation is based on the assumption that the project is the same as the project for which the [Import SDK] was performed.

Attach CubismMotionController to the model

Attach CubismMotionController to the GameObject that will be the root of Cubism’s Prefab placed in the Scene.

If it is already attached, there is no need to attach a new one.
If a component that plays motion using CubismMotionController is attached, be careful of interference with the following settings.

In CubismFadeController.CubismFadeMotion, set the .fadeMotionList in which the ID of the AnimationClip to be played in a loop is registered.

Create a script to perform loop playback processing

Create a C# script in the Project window.

Here the name is “CubismMotionLoopPlayer.”

Attach the created script to the same level as CubismMotionController in Prefab.

Use a text editor to open the created script and rewrite it as follows.

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

public class CubismMotionLoopPlayer : MonoBehaviour
{
    // AnimationClip to be played in a loop
    [SerializeField]
    public AnimationClip Animation;

    private CubismMotionController _motionController;


    private void Start()
    {
        _motionController = GetComponent<CubismMotionController>();
        
        
        // Loop playback of motions
        _motionController.PlayAnimation(Animation);
    }
}

With the Prefab in the Scene selected, set the AnimationClip to be looped to CubismMotionLoopPlayer.Animation from the Inspector window.

If you play the scene with the above settings, the motion will be played back in a loop, but no fade will occur during the loop.

CubismMotionController implements a function to register a callback to be called at the end of motion playback.

    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, float instanceId)
        {
            _motionPriorities[layerIndex] = CubismMotionPriority.PriorityNone;

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

        #endregion
        
        ...

Using this, modify the aforementioned CubismMotionLoopPlayer so that it does not directly loop playback, but instead plays back the same motion again when the motion playback ends.
CubismMotionController.AnimationEndHandler callback will not be called if isLoop in CubismMotionController.PlayAnimation() is passed true.

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>();
        
        
        // Register a callback function in the handler of CubismMotionController
        _motionController.AnimationEndHandler += OnAnimationEnded;
        
        
        // Let the motion play directly only the first time
        OnAnimationEnded(0);
    }


    // Callback when the motion has finished playing
    private void OnAnimationEnded(float instanceId)
    {
        // Motion playback (loop playback disable
        _motionController.PlayAnimation(Animation, isLoop:false);
    }
}

This completes the setup.

When the scene is played back in this state, the motion will fade while looping.

Please let us know what you think about this article.