Callback for End of Motion Playback (Java)

Updated: 01/26/2023

This page is for Cubism version 4.2 or earlier. Click here for the latest version.


Cubism SDK for Java  allows callbacks to retrieve events when motion playback ends.
In the sample, the callback function outputs log text to notify of the end of playback.

Callback Implementation

In order to use callbacks when motion playback ends, callbacks have been implemented in Framework/src/motion/ACubismMotion, an abstract class that manages motion.

public class ACubismMotion{
    // モーション再生終了コールバックの登録
    public void setFinishedMotionHandler(IFinishedMotionCallback onFinishedMotionHandler) {
        onFinishedMotion = onFinishedMotionHandler;

    // モーション再生終了コールバックの取得
    public IFinishedMotionCallback getFinishedMotionCallback() {
        return onFinishedMotion;

    // モーション再生終了時に呼び出されるコールバック関数を入れる変数
    protected IFinishedMotionCallback onFinishedMotion;
* Interface used as end-of-motion playback callback
public interface IFinishedMotionCallback {
    public void execute(ACubismMotion motion);

Cubism SDK for Java reproduces the callback mechanism using an object that implements the interface defined for callbacks.


Please note that in the sample, callbacks cannot be invoked under the following conditions.

  • When the motion being played is set as “looping”
  • When null is registered in the callback

Use Callback Functions

Implement what you actually want to be processed in the callback function.

In the sample, log text notifying of the end of motion playback is implemented to be output using the LAppPal.printLog method.
To change the processing at the end of motion playback, change the implementation of the following function.

private static class FinishedMotion implements IFinishedMotionCallback {
    public void execute(ACubismMotion motion) {
        LAppPal.printLog("Motion Finished: " + motion);

The callback method is registered when CubismUserMotion.loadMotion method is used in the Framework layer to load motion data, and the callback method is passed at the same time the motion is generated.
When there is already a motion, setFinishedMotionHandler() introduced in “Callback Implementation” is used.

public int startMotion(
    final String group,
    int number,
    int priority,
    IFinishedMotionCallback onFinishedMotionHandler
) {
    if (motion == null) {
        String fileName = modelSetting.getMotionFileName(group, number);
        if (!fileName.equals("")) {
            String path = modelHomeDirectory + fileName;
            byte[] buffer = LAppPal.loadFileAsBytes(path);

            // モーションデータを読み込むのと同時にコールバック関数オブジェクトを渡して登録する
            motion = loadMotion(buffer, onFinishedMotionHandler);
    } else {

In the sample, the callback function is passed from startRandomMotion(), which is called when onTap() is executed to obtain the tap event.
In addition, since CubismMotion.doUpdateParameters() is actually playing back the motion, the implementation is made so that the callback function can be passed to CubismMotion.

public static CubismMotion create(byte[] buffer, IFinishedMotionCallback callback) {
    CubismMotion result = new CubismMotion();

    result.sourceFrameRate = result.motionData.fps;
    result.loopDurationSeconds = result.motionData.duration;

    // コールバック関数の登録
    result.onFinishedMotion = callback;

    return result;

On the Development of Implementation

In the sample, only the end of motion playback is implemented, but by developing the implementation, asynchronous processing can be used in callback functions after motion playback is finished.
Alternately, by reversing the function from the actual process to which the callback is to be applied, callbacks can be implemented at points other than the end of motion playback.

Was this article helpful?
Please let us know what you think about this article.