Control the Order of Execution of Your Own Components (SDK for Cocos Creator)

Updated: 03/14/2023

This section describes the procedure for controlling the order of execution among other Cubism components for a user’s own component.
The following explanation is based on the assumption that the project is the same as the project for which the “Import SDK” was performed.

Summary

Some components in the Original Workflow of the Cubism SDK for Cocos Creator have restrictions on the order in which they are executed.

In Cubism SDK for Cocos Creator, this can be controlled by using CubismUpdateController, which controls the execution order of the above components.
The component controlled by CubismUpdateController will be the component attached to the root of the Prefab of the Cubism model.

With CubismUpdateController, the user’s own components can be controlled in the same order of execution.

As an example, this section describes the procedure for setting up execution order control for the following components.

@ccclass('CubismExampleController')
export class CubismExampleController extends Component {
    start() {
        // Initialization process of CubismExampleController
    }

    lateUpdate(deltaTime: number) {
        // Update process of CubismExampleController
    }
}

1. Attach Components to Prefab

Attach CubismExampleController to the root Node of the Prefab placed in the Hierarchy.
If Prefab is not imported in OW format, CubismUpdateController is also attached.

2. Implement ICubismUpdatable in the Component

Implement the ICubismUpdatable interface in the component that controls the execution order.

CubismUpdateController retrieves components that implement ICubismUpdatable at runtime and controls the order in which they are executed.

@ccclass('CubismExampleController')
export class CubismExampleController extends Component implements ICubismUpdatable {

  bindedOnLateUpdate: ICubismUpdatable.CallbackFunction;
  get executionOrder(): number {
    throw new Error('Method not implemented.');
  }
  get needsUpdateOnEditing(): boolean {
    throw new Error('Method not implemented.');
  }
  get hasUpdateController(): boolean {
    throw new Error('Method not implemented.');
  }
  set hasUpdateController(value: boolean) {
    throw new Error('Method not implemented.');
  }

  readonly [ICubismUpdatable.SYMBOL]: typeof ICubismUpdatable.SYMBOL;

  protected start() {
    // Initialization process of CubismExampleController
  }

  protected lateUpdate(deltaTime: number) {
    // Update process of CubismExampleController
  }
}

The ICubismUpdatable interface implemented here is as follows.

interface ICubismUpdatable {
  readonly [ICubismUpdatable.SYMBOL]: typeof ICubismUpdatable.SYMBOL;
  readonly bindedOnLateUpdate: ICubismUpdatable.CallbackFunction;

  get executionOrder(): number;
  get needsUpdateOnEditing(): boolean;
  get hasUpdateController(): boolean;
  set hasUpdateController(value: boolean);
}

The executionOrder is the value that determines the order of execution for this component.
The smaller this value, the earlier it is called in relation to other components.
The values set for the components included with the SDK are described in the CubismUpdateExecutionOrder.

The hasUpdateController is a flag that allows components implementing ICubismUpdatable to be called from Cocos Creator event functions if the CubismUpdateController is not attached.

namespace CubismUpdateExecutionOrder {
  export const CUBISM_FADE_CONTROLLER = 100;
  export const CUBISM_PARAMETER_STORE_SAVE_PARAMETERS = 150;
  export const CUBISM_POSE_CONTROLLER = 200;
  export const CUBISM_EXPRESSION_CONTROLLER = 300;
  export const CUBISM_EYE_BLINK_CONTROLLER = 400;
  export const CUBISM_MOUTH_CONTROLLER = 500;
  export const CUBISM_HARMONIC_MOTION_CONTROLLER = 600;
  export const CUBISM_LOOK_CONTROLLER = 700;
  export const CUBISM_PHYSICS_CONTROLLER = 800;
  export const CUBISM_RENDER_CONTROLLER = 10000;
  export const CUBISM_MASK_CONTROLLER = 10100;

3. Make Components Compatible with CubismUpdateController

Modify CubismExampleController as follows.
import { _decorator, Component, Node } from 'cc';
import CubismUpdateController from '../../extensions/Live2DCubismSdkForCocosExtension/static/assets/Framework/CubismUpdateController';
import ICubismUpdatable from '../../extensions/Live2DCubismSdkForCocosExtension/static/assets/Framework/ICubismUpdatable';
const { ccclass, property } = _decorator;

@ccclass('CubismExampleController')
export class CubismExampleController extends Component implements ICubismUpdatable {
  bindedOnLateUpdate: ICubismUpdatable.CallbackFunction;

  // Execution order of this component
  get executionOrder(): number {
      return 150;
  }

  // Whether the order of execution is controlled during non-execution of a Scene
  get needsUpdateOnEditing(): boolean {
      return false;
  }

  // Whether the order of execution is controlled
  @property({ serializable: false, visible: false })
  private _hasUpdateController: boolean = false;
  get hasUpdateController(): boolean {
      return this._hasUpdateController;
  }
  set hasUpdateController(value: boolean) {
      this._hasUpdateController = value;
  }

  readonly [ICubismUpdatable.SYMBOL]: typeof ICubismUpdatable.SYMBOL;

  protected start() {
    // Initialization process of CubismExampleController

    // Check if CubismUpdateController is attached to the model’s Prefab
    this.hasUpdateController = this.getComponent(CubismUpdateController) ! = null;
  }

  protected lateUpdate(deltaTime: number) {
    // If CubismUpdateController is not attached, update process is performed from CubismExampleController’s own event function
    if (!this.hasUpdateController) {
        this.onLateUpdate(deltaTime);
    }
  }

  // Update functions which are controlled by the order of execution
  public onLateUpdate(deltaTime: number) {
    // Update process of CubismExampleController
  }
}

The update process performed by lateUpdate() is moved to onLateUpdate(), which is called by CubismUpdateController.

This completes the setup for controlling the order of execution.
When this script is attached to the Prefab of the Cubism model and the scene is executed, the update process of this script is called by the CubismUpdateController.

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