前からLive2Dモデルの位置やサイズ調整する場合、行列をかけるのが正しいと思ってました。
今まで自己流で位置やサイズ調整してたけど、正しいやり方をやっと理解できました!
詳しくは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());
スライダーで動かしてみる
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つすっきりした。