ガレージ暮らしのトライタム

プログラムやツールの解説や技術を公開する場所

【Live2DSDK】CubismSDK for UnityのUserEventで複数メソッドを呼ぶ

はじめに

公式チュートリアルではmotion3.jsonを扱う時、1つのメソッドを利用しているが複数のメソッドを使いたい時はどうすればいいかという記事です。
motion3.jsonに設定されたユーザデータを取得 | Live2D Manuals & Tutorials

最後のDebug.Logの出力までの大体の流れは同じです。
走らせたいメソッドの用意(新規スクリプト)、CubismMotion3Json.csの加筆の後にモデル+イベントのついたモーションをUnityへインポートします。
一度公式チュートリアルを試し、流れを把握してから本記事で改良を行うことをお勧めします。

用意するスクリプト

新規スクリプト

Unityで新規スクリプトを作成します。
以下はサンプルコードです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MultiUserEvent: MonoBehaviour
{
    public void Listener(AnimationEvent animationEvent)
    {
        var currentState = GetComponent<Animator>().GetCurrentAnimatorStateInfo(0);

        Debug.Log("Time : " + (currentState.length / currentState.speed) + "\n" +
            "Value : " + animationEvent.functionName);
    }

    public void Listener02(AnimationEvent animationEvent)
    {
        var currentState = GetComponent<Animator>().GetCurrentAnimatorStateInfo(0);

        Debug.Log("Time : " + (currentState.length / currentState.speed) + "\n" +
            "Value : " + animationEvent.functionName);
    }
}

CubismMotion3Json.csの編集

CubismMotion3Jsonではインポート時にモーションがイベントを持っていれば対応することが出来る記述があります。
公式チュートリアルを参考にすると1つのメソッドを扱う時は以下のコードで問題ありません。

      var animationEvent = new AnimationEvent
      {
          time = UserData[i].Time,
          functionName = "Listener",    // 追加した行
          stringParameter = UserData[i].Value,
      };

ただこれでは1つのメソッドしか呼ぶことが出来ないのでいくつもUserEventがあり、いくつもメソッドをそれぞれに呼びたい場合は対応が難しくなります。
端的に言えばnewするタイミングでifやswitchで分岐させれば対応するメソッドをいくつも使う事ができます。
今回はモーションに付けられるEventの文章から条件分岐を行っています。

2つメソッドを使いたい場合

ifかswitchで行うほかに三項演算子で記述できます。ここではifと三項演算子のサンプルコードを示します。
ifの場合は以下のように、

 if (UserData[i].Value == "event01")
 {
     var animationEvent = new AnimationEvent
     {
         time = UserData[i].Time,
         functionName = "Listener",    // 追加した行
         stringParameter = UserData[i].Value,
     };
     animationEvents.Add(animationEvent);
 }
 else
 {
     var animationEvent = new AnimationEvent
     {
         time = UserData[i].Time,
         functionName = "Listener02",    // 追加した行
         stringParameter = UserData[i].Value,
     };
     animationEvents.Add(animationEvent);
 }

三項演算子の方は、以下のコードのようになります。

var animationEvent = new AnimationEvent
{
    time = UserData[i].Time,
    functionName = (UserData[i].Value == "event01") ? "Listener" : "Listener02",
    stringParameter = UserData[i].Value,
};

Valueで取っているのはCubismEditorでモーション作成時に入れた文章になっています。
f:id:traitam:20180912190900p:plain

他にも記述が必要な場合は、splitなどで一度分岐処理用の文字列を抽出してから行うと良いのかもしれません。
メソッド2つだけであれば三項演算子の方がスッキリするのでお勧めです。

3つ以上メソッドを使いたい場合

こちらもifかswitchで分岐を行うと良いです。

ただnewのタイミングで3つ以上分岐が並んでいたりswitchが列挙されていると冗長になってしまいます。メソッドとして切り出し、判別用stringを引数として判別するのが良いと思われます。
コールバック用メソッド名もベタ打ちではなく配列に格納したりするとコードをスッキリしそうですね。
それでもコードの汚さを無視しても良いのなら、同じ記述たくさんでもいいと思います。ifたくさんとかswitchまみれとか。出来ればよいのです。…っていうと色んな人から怒られそう

その他必要な作業

今回は2つのイベント用メソッドを用意しての確認です。
CubismEditorで2つ以上イベントが登録されているモーションを用意します。1つには“event01”と記述します。
その後モーションをUnityへインポートします。スクリプトを作成した後にインポートしないとイベントが登録されないので注意が必要です。
既にいれてしまった場合はモデルフォルダ右クリック->ReImportを押してインポートしなおしましょう。

動作確認

特に問題が無ければ以下のように2つのメソッドが呼ばれたことが確認できると思います。
f:id:traitam:20180912192228p:plain

思わぬ動作になった場合は文字列のタイピングミスやCubismMotion3Jsonの加筆後にモデルやモーションを再インポートしたか確認してください。


では、皆さまよき創作ライフを。