Live2DでJSON対応のUnityコード書いた | とあるプログラマーのブログ

とあるプログラマーのブログ

Unityやblender、Live2Dについて書いていきます!

Live2D Animatorで出力したモーション(mtn)をUnityに配列で渡してみた。
そしたらInSpectorがこんなになった~


うわ~、これはなんか見た目がつらい...
Live2DのUnity SDKのサンプルコードみたいにJSONで管理する事にしました。



JSONは Live2D Viewer というソフトで出力できます(無料)
Viewerでは髪の物理演算など付けられるし、SDKにJSON読込コードはある。
ただ、自分で制御するコードをどこに書けばいいか分かり辛い...


 [Live2DのJSON読込サンプル]
 sampleApp1を利用したプロジェクト作成


なので、自分用に使いやすいコードを書きました。
JSONの解析は、使いやすそうなMiniJSONをDLして使った。

 
UnityでJSONをあつかう - MiniJSON
  → 使うのは中にあるMiniJSON.csのみ




JSON化の手順
(1)mocとmtnファイルをViewerにDrag&Dropする


(2)soundは、mtnを選択して1つずつ付けていきます
 再生ボタン押しても公式マニュアルの通り、MP3しか音は出ません
  → 公式マニュアル - モーションの設定



(3)[ファイル]-[書き出し]-[モデル設定ファイル(サンプル用)]でJSON出力


(4)bytes拡張子を付けてjsonをUnityに取り込み



(5)DLしてきたAssets/MiniJSON.csだけをScript配下に置く


(6)以下のソースをLive2Dモデルのソースに追加
 [main.cs]

using UnityEngine;
using System.Collections;
using MiniJSON;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using live2d;

public class main : MonoBehaviour {
    public TextAsset modelJson;         // model.json
    private TextAsset mocFile;          // モデルファイル
    private Texture2D[] texture;        // テクスチャファイル
    private TextAsset[] mtnFile;        // モーションファイル
    private AudioClip[] soundFile;      // 音声ファイル
    private Live2DModelUnity live2DModel;
    private Live2DMotion motion;                // モーションクラス
    private MotionQueueManager motionManager;   // モーション管理クラス
    private int cnt = 0;    // ファイル項番


    void Start (){
        // JSONを読み込む
        Json_Read();
        // Live2D初期化
        Live2D.init();
        live2DModel = Live2DModelUnity.loadModel(mocFile.bytes);
        for(int i = 0; i < texture.Length; i++)
        {
            live2DModel.setTexture( i, texture[i] ) ;
        }
        // モーション管理クラスのインスタンス作成
        motionManager = new MotionQueueManager();
        // モーションのインスタンスの作成
        motion = Live2DMotion.loadMotion(mtnFile[0].bytes);
        // モーションの再生
        motionManager.startMotion(motion,false);
        // ボイス再生
        audio.clip = soundFile[0];
        audio.Play();
    }


    /// 
    /// JSONを読み込む
    /// 
    void Json_Read (){
        //JSONテキストのデコード
        var jsonData = MiniJSON.Json.Deserialize (modelJson.text) as Dictionary;
        // モデル読込
        string model = (string)jsonData ["model"];
        Debug.Log(jsonData ["model"].GetType());
        mocFile = new TextAsset();
        mocFile = (Resources.Load(model,typeof(TextAsset)) as TextAsset);
        // テクスチャ読込
        IList textureList = (IList)jsonData ["textures"];
        int n = 0;
        texture = new Texture2D[textureList.Count];
        foreach (string txtNm in textureList) {
            // 不要な拡張子を削除
            string pngNm = Regex.Replace(txtNm, ".png$", "");
            texture[n] = (Resources.Load(pngNm,typeof(Texture2D)) as Texture2D);
            n++;
        }
        // モーション読込
        IDictionary motions = (IDictionary)jsonData ["motions"];
        IList nulllist = (IList)motions ["null"];
        IList file = (IList)nulllist;
        int i = 0;
        mtnFile = new TextAsset[file.Count];
        soundFile = new AudioClip[file.Count];
        foreach (IDictionary mtnNm in file) {
            mtnFile[i] = (Resources.Load((string)mtnNm["file"],typeof(TextAsset)) as TextAsset);
            string soundNm = Regex.Replace((string)mtnNm["sound"], ".wav$", "");
            soundFile[i] = (Resources.Load(soundNm,typeof(AudioClip)) as AudioClip);
            i++;
        }
    }


    void Update(){
        // aキー押されたらモーション切替
        if(Input.GetKeyDown("a")){
            if(cnt >= mtnFile.Length - 1){
                cnt = 0;
            }
            cnt++;
            // モーションのロードをする
            motion = Live2DMotion.loadMotion(mtnFile[cnt].bytes);
            // フェードアウトは0
            motion.setFadeOut(0);
            // モーションスタート
            motionManager.startMotion(motion,false);
            // ボイス再生
            audio.clip = soundFile[cnt];
            audio.Play();
        }
    }


    /// 
    /// カメラがシーンにレンダリングに呼ばれる
    /// 
    void OnRenderObject(){
        // 描画位置を指定
        Matrix4x4 m1=Matrix4x4.Ortho(0,1000.0f,1000.0f,0,-0.5f,0.5f);
        Matrix4x4 m2 = transform.localToWorldMatrix;
        Matrix4x4 m3 = m2*m1;
        live2DModel.setMatrix(m3);

        if( live2DModel == null ) return ;
        // 頂点の更新
        live2DModel.update();
        // モデルの描画
        live2DModel.draw();
    }
}

※ 最後に入ってる</string,object>は無視して下さい
  なぜかamebaだと入っちゃう

(7)Inspectorにjsonをセットするだけ(moc、texture、motion、soundを解析)


すげーすっきりしたけど、プログラムの実装進んでないという


もし表示されない場合は、jsonのパスが合ってるか確認して下さい。
物理演算も読み込めるように、そのうち対応してgithubにUPしよっと