複数Live2Dモデルの描画順を制御する

  • 11
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

複数のLive2Dモデルを表示する場合、描画順をZ値で上手く制御できなかったのでやり方をまとめてみました。
01.gif

主にやり方は以下の2つありました。

1.描画タイミングを管理するスクリプト作る

Live2D コミュニティで以下のスレッドがあったので、SDKのMotionプロジェクトをカスタムして試してみました。
 → UnityでLive2dを使うときに描画順を制御するにはどうしたらいいでしょうか?

1)まずは2体のLive2Dモデルを用意します(スクリプトは同じものをアタッチ)
02.png

2)SimpleModel.csのOnrenderObject()を適当な名前に変えます

SimpleModel.cs
    //void OnRenderObject()
    public void RenderLive2D()
    {
        if (live2DModel == null) return;
        live2DModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos);
    .
    .
    .

3)空のGameObjectを作り、スクリプトを作ります
03.png

RenderControl.cs
using UnityEngine;
using System.Collections;

public class RenderControl : MonoBehaviour {

    [Range(0,1)]
    public int changemodel; // 前面に出すモデル切替

    private SimpleModel obj_haru;       // haruモデル
    private SimpleModel obj_Epsilon;    // Epsilonモデル

    void Start () {
        // スクリプトを取得する
        obj_haru = GameObject.Find("haru").GetComponent<SimpleModel>();
        obj_Epsilon = GameObject.Find("Epsilon").GetComponent<SimpleModel>();
    }

    void OnRenderObject(){
        if (changemodel == 0)
        {
            obj_haru.RenderLive2D();
            obj_Epsilon.RenderLive2D();
        }
        else
        {
            obj_Epsilon.RenderLive2D();
            obj_haru.RenderLive2D();
        }
    }
}

これで描画順を制御できます!
04.gif
書き終わってから指摘を受けたけど、Live2DモデルのZ値でどっちを先に描画するか指定する方が賢いですね

2.描画モードを変更しZ値で制御する

もう1つのやり方が描画モードをDRAW_MESH_NOWからDRAW_MESHに変更する方法です。
 → Live2D Manual - 描画モードの設定について

こちらはスクリプトを以下のように描画モードとOnRenderObjectをUpdateに変更するだけです。

2015/09/17追記
Live2D Unity SDK2.1からクリッピングマスク使用モデルの場合はlive2DModel.updateのタイミングが変更

SimpleModel.cs
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using live2d;

[ExecuteInEditMode]
public class SimpleModel: MonoBehaviour 
{
    private Live2DModelUnity live2DModel;
    private Live2DMotion motion;
    private MotionQueueManager motionMgr;
    private Matrix4x4 live2DCanvasPos;
    public TextAsset mocFile ;
    public Texture2D[] textureFiles ;
    public TextAsset motionFile;

    void Start () 
    {
        Live2D.init();

        live2DModel = Live2DModelUnity.loadModel(mocFile.bytes);
        // Live2Dのレンダーモード変更
        live2DModel.setRenderMode(Live2D.L2D_RENDER_DRAW_MESH);

        for (int i = 0; i < textureFiles.Length; i++)
        {
            live2DModel.setTexture(i, textureFiles[i]);
        }

        float modelWidth = live2DModel.getCanvasWidth();
        live2DCanvasPos = Matrix4x4.Ortho(0, modelWidth, modelWidth, 0, -50.0f, 50.0f);

        motionMgr = new MotionQueueManager();
        motion = Live2DMotion.loadMotion(motionFile.bytes);
    }

    //void OnRenderObject()
    public void Update()
    {
        if (live2DModel == null) return;
        live2DModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos);

        if ( ! Application.isPlaying)
        {
            live2DModel.update();
            live2DModel.draw();
            return;
        }

        if (motionMgr.isFinished())
        {
            motionMgr.startMotion(motion);
        }

        motionMgr.updateParam(live2DModel);

        live2DModel.update();
        live2DModel.draw();
    }
}

こちらの方式ならZ値をいじるだけで描画順を制御できます
05.gif

また、パーティクルなども描画順が制御できます。

ただ、Live2Dの描画の裏側の話のスライドにもあった通り、こちらは削除されるAPI方式です。
Unity5.0.1で確認しましたが、まだ使えるAPIっぽいのでやりやすい方で描画順を制御すればOKかと思います。

3.RenderTextureを使う

Live2D Unity SDKにはRenderTextureプロジェクトがあります。
こちらならRenderTextureを使ってPlaneにLive2Dモデルを表示するので、普通の3Dオブジェクトと同じように扱えます。
Unity5になってFree版でもRenderTextureが使えるようになったので、使うといいです。

ただし、通常よりもドローコール数が2倍になります。

参考 → Q. 半透明のマテリアルを設定したゲームオブジェクトが、Live2Dのモデルの前に表示できません。