Unity
Live2D

Live2DのCubism3モデルを動的に読み込んでアレコレするメモ

※モデルファイルを動的に読み込むプログラムはSDK規約における「拡張性アプリケーション」に該当します。配布するときには個別契約を忘れずにしましょう。

SDKはUnityのR5でのお話

model3.jsonの読み込み

Live2D>Cubism>Framework>Json>CubismModel3Json.csを使って読み込み

XXX.cs
class XXX
{
   private CubismModel3Json modeljson;
   private CubismModel c3model;

   public XXX(string jsonpath)
   {
        modeljson = CubismModel3Json.LoadAtPath(jsonpath, normalFileLoad); //★通常ファイル読み込み用の静的メソッドを作ってそれを渡す
        c3model = modeljson.ToModel();
   }

   private static object normalFileLoad(Type assetType, string assetPath)
   {
        if (assetType == typeof(byte[]))
        {
            return File.ReadAllBytes(assetPath);
        }
        else if (assetType == typeof(string))
        {
            return File.ReadAllText(assetPath);
        }
        else if (assetType == typeof(Texture2D))  //★textureは別個で追加しないとダメだった
        {
            Texture2D r = new Texture2D(0, 0);
            r.LoadImage(File.ReadAllBytes(assetPath));

            return r;
        }

        return File.ReadAllBytes(assetPath);
    }
}

あとでモデルのgameObjectにモーション制御用のAnimationとか音声制御用のAudioSorceをくっつけてやる
削除のときはモデルについているgameObjectをDestroy。メインスレッドでやること

motion3.jsonの読み込み 再生

XXX.cs
class XXX
{
    //core objects
    private CubismModel3Json modeljson;
    private CubismModel c3model;

    //path & names
    private string _callCode;
    private string dirPath;
    private string luaScriptPath;
    private string matrixFilePath;

    //option objects
    private Dictionary<string, AudioClip> audios = new Dictionary<string, AudioClip>();
    private AudioSource nowPlayAudio;
    private Animation animeController;

    public XXX(string jsonpath)
    {
        modeljson = CubismModel3Json.LoadAtPath(jsonpath, normalFileLoad);
        c3model = modeljson.ToModel();

        renderController = c3model.gameObject.GetComponent<CubismRenderController>();

        //★モーションコントロール用Animation
        animeController = c3model.gameObject.AddComponent<Animation>();
        animeController.playAutomatically = false;

        //★こっちは一緒に再生する音声制御用
        nowPlayAudio = c3model.gameObject.AddComponent<AudioSource>();
        nowPlayAudio.playOnAwake = false;

        var filename = FileManager.getFilename(jsonpath);
        dirPath = FileManager.getDirName(jsonpath);
        _callCode = filename.Replace(".model3.json", "");

        //★モデルjsonには標準で登録する機能がないので.motion3.jsonを漁る
        string[] motionFiles = Directory.GetFiles(dirPath, "*.motion3.json", System.IO.SearchOption.AllDirectories);
        foreach(var e in motionFiles)
        {
            //★jsonを読み込む
            CubismMotion3Json cm3json = CubismMotion3Json.LoadFrom((string)normalFileLoad(typeof(string),e));
            if(cm3json != null)
            {
                string callname = FileManager.getFilename(e).Replace(".motion3.json", "");
                var aclip = cm3json.ToAnimationClip();
                aclip.legacy = true;  //★レガシーにしないと動作してくれない
                animeController.AddClip(aclip, callname); //★モーションの登録

                var soundfilepath = e.Replace(".motion3.json", ".wav");
                if (File.Exists(soundfilepath))
                {
                    audios.Add(callname, GFileManager.LoadSoundFile(soundfilepath));
                }
            }
        }
        startTimeMSec = UtSystem.getUserTimeMSec();
    }

    public void motionStart(string name)
    {
        animeController.Play(name);
        if (audios.ContainsKey(name))
        {
            nowPlayAudio.clip = audios[name];
            nowPlayAudio.Play();
        }
    }