Help us understand the problem. What is going on with this article?

Live2Dで位置とサイズを調整する

More than 3 years have passed since last update.

前からLive2Dモデルの位置やサイズ調整する場合、行列をかけるのが正しいと思ってました。
今まで自己流で位置やサイズ調整してたけど、正しいやり方をやっと理解できました!
000.gif

詳しくはLive2Dコミュニティに書いてあります。
 → UnityでLive2Dモデルを表示した際の拡縮率は?

開発環境

Live2D Cubism SDK WebGL 2.0のSimpleプロジェクトをカスタム
 → WebGL版を使いますが、他のプラットフォームでもほぼ同様

ソースコード

まずはHTML部分にLive2DFramework.jsを追加します。この中に含まれるL2DMatrix44クラスを使います。

simple.htmlの12行目あたり
<!-- Live2D Library -->
<script src="../../lib/live2d.min.js"></script>
<script src="../../framework/Live2DFramework.js"></script>
<!-- User's Script -->
<script src="src/Simple.js"></script>

Simple.draw()部分の行列部分を以下のように修正します。
setWidth()でサイズ調整、setCenterPosition()で位置調整ができます!
要するにsetWidth()などの返り値(行列)を配列に変換して、配列をセットしてやるだけです。

Simple.jsの150行目あたり
// 表示位置を指定するための行列を定義する
//    var s = 2.0 / live2DModel.getCanvasWidth(); //canvasの横幅を-1..1区間に収める
//    var matrix4x4 = [
//        s, 0, 0, 0,
//        0,-s, 0, 0,
//        0, 0, 1, 0,
//       -1, 1, 0, 1
//   ];
//    live2DModel.setMatrix(matrix4x4);

    // 描画してるLive2Dモデルのサイズを取得
    var height = live2DModel.getCanvasHeight();
    var width = live2DModel.getCanvasWidth();
    // Live2D用の行列定義
    var mmat = new L2DModelMatrix(width, height);
    // サイズ(幅)
    mmat.setWidth(2.0);
    // ポジション(X, Y)
    mmat.setCenterPosition(0.0, 0.0);
    // 配列をセット
    live2DModel.setMatrix(mmat.getArray());

スライダーで動かしてみる

スライダーをつければこんな感じに操作できます。
001.gif

HTML側にはスライダーをつけます。

simple.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
        <title>Live2D Simple</title>
    </meta>
</head>

<body onload="Simple()">
    <canvas id="glcanvas" width = "400px" height="400px" style="border:dashed 1px #CCC"></canvas>
    <div id="myconsole" style="color:#BBB">---- Log ----</div>
    サイズ(幅)<input type="range" id="L2D_WIDTH" value="2.0" min="0.0" max="5.0" step="0.1">
    <br>
    位置X<input type="range" id="L2D_X" value="0.0" min="-3.0" max="3.0" step="0.1">
    <br>
    位置Y<input type="range" id="L2D_Y" value="0.0" min="-3.0" max="3.0" step="0.1">
    <!-- Live2D Library -->
    <script src="../../lib/live2d.min.js"></script>
    <script src="../../framework/Live2DFramework.js"></script>
    <!-- User's Script -->
    <script src="src/Simple.js"></script>
</body>
</html>

スライダーで動的に位置やサイズを変える場合、先ほどと違いLive2D初期化処理のカッコ外で行います。

Simple.jsの150行目あたり
var l2d_scale, l2d_x, l2d_y; // スライダー用

Simple.draw = function(gl/*WebGLコンテキスト*/)
{
    // Canvasをクリアする
    gl.clear(gl.COLOR_BUFFER_BIT);

    // Live2D初期化
    if( ! live2DModel || ! loadLive2DCompleted )
        return; //ロードが完了していないので何もしないで返る

    // ロード完了後に初回のみ初期化する
    if( ! initLive2DCompleted ){
        initLive2DCompleted = true;

        // 画像からWebGLテクスチャを生成し、モデルに登録
        for( var i = 0; i < loadedImages.length; i++ ){
            //Image型オブジェクトからテクスチャを生成
            var texName = Simple.createTexture(gl, loadedImages[i]);

            live2DModel.setTexture(i, texName); //モデルにテクスチャをセット
        }

        // テクスチャの元画像の参照をクリア
        loadedImages = null;

        // OpenGLのコンテキストをセット
        live2DModel.setGL(gl);
        // スライダーを取得
        l2d_scale = document.getElementById("L2D_WIDTH");
        l2d_x = document.getElementById("L2D_X");
        l2d_y = document.getElementById("L2D_Y");
        // 表示位置を指定するための行列を定義する
//        var s = 2.0 / live2DModel.getCanvasWidth(); //canvasの横幅を-1..1区間に収める
//        var matrix4x4 = [
//            s, 0, 0, 0,
//            0,-s, 0, 0,
//            0, 0, 1, 0,
//           -1, 1, 0, 1
//       ];
//        live2DModel.setMatrix(matrix4x4);
//
    }
            // 描画してるLive2Dモデルのサイズを取得
            var height = live2DModel.getCanvasHeight();
            var width = live2DModel.getCanvasWidth();
            // Live2D用の行列定義
            var mmat = new L2DModelMatrix(width, height);
            // サイズ(幅)
            mmat.setWidth(l2d_scale.value);
            // ポジション(X, Y)
            mmat.setCenterPosition(l2d_x.value, l2d_y.value);
            // 配列をセット
            live2DModel.setMatrix(mmat.getArray());

    // キャラクターのパラメータを適当に更新
    var t = UtSystem.getTimeMSec() * 0.001 * 2 * Math.PI; //1秒ごとに2π(1周期)増える
    var cycle = 3.0; //パラメータが一周する時間(秒)
    // PARAM_ANGLE_Xのパラメータが[cycle]秒ごとに-30から30まで変化する
    live2DModel.setParamFloat("PARAM_ANGLE_X", 30 * Math.sin(t/cycle));

    // Live2Dモデルを更新して描画
    live2DModel.update(); // 現在のパラメータに合わせて頂点等を計算
    live2DModel.draw(); // 描画
};

今までどうやってやるのか疑問だったけど、1つすっきりした。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away