Live2D
TyranoScript
ティラノスクリプト

最新のティラノスクリプト×Live2Dの開発環境を構築する

More than 1 year has passed since last update.

マルチプラットフォームに対応可能な無料のJavaScriptノベルゲームエンジン・ティラノスクリプト
ティラノスクリプトは、専用のプラグインを読み込むことで、Live2Dのモデルを扱うことができます。
それに関連するこの記事では、以下の項目の達成を目標として解説を行います。

  • 最新のティラノスクリプトでLive2Dのモデルを扱える環境を構築する。
  • 構築した環境で実際に独自モデルを追加・操作する知識を身に着ける。

1. 環境の構築

1-1. 準備するもの

環境の構築にあたって、次のソフトウェアが必要です。

  • 適当なZipファイル解凍ツール

1-2. ダウンロードと解凍

まず、環境の構築に必要なファイルをすべてダウンロードしてしまいましょう。
バージョンが複数ある場合、基本的に最新のバージョンをダウンロードします。

  1. こちらから、ティラノスクリプト(スタンダードパッケージ)をダウンロードする。
  2. こちらから、Live2Dプラグインをダウンロードする。(※)
  3. こちらから、Live2D SDK WebGLをダウンロードする。(※)
  4. こちらから、ティラノスクリプト公式Live2Dモデルをダウンロードする。

※ダウンロードには利用規約への同意が必要です。
 また、アンケートへの回答を求められる場合があります。

すべてをダウンロードすると、次のZipファイル群が揃うはずです。
(ファイル名の「v213」や「v457」などの部分は最新のバージョンが何かで変わります。)
手持ちのZip解凍ソフトウェアですべて解凍してしまいましょう。

  01.png
  
   :arrow_down: 解凍!:arrow_down:

  02.png

このとき、Zipファイルを解凍すると「__MACOSX」というフォルダや
.DS_Store」というファイルが出てくることがあります。

  03.png

これはMacで圧縮されたZipファイルをWindowsで解凍した場合に出てくるもので、
とくに必要のないファイルです。したがって、すべて削除してよいです。
ファイル名で検索してから一括削除するとスムーズでしょう。

1-3. Live2D SDK の移動

「Live2D_SDK_WebGL_2.1.00_1_jp/lib/live2d.min.js」ファイルを、
tyrano_live2dplugin_v213/data/others/live2d/lib」フォルダにコピーします。

  04.png

1-4. Live2D プラグインの移動

実は、この段階で「tyrano_live2dplugin_v213/index.html」を起動すれば、
すでにLive2Dがティラノスクリプトで動いていることを確認できます。

しかしバージョンが問題で、Live2Dプラグインが含まれているティラノスクリプトの
パッケージ「tyrano_live2dplugin_v213」のバージョンは4.10です。古いです。
したがって、最新のティラノスクリプトへの移行を行います。

「tyrano_live2dplugin_v213/scenario」と「tyrano_live2dplugin_v213/others」の
両フォルダを、「tyranoscript_v457/data」フォルダにコピー(上書き)します。

  05.png

これで、最新のティラノスクリプトでLive2Dを扱う準備ができました。
さらに、独自モデルを追加して動かしていきます。

2. 独自モデルを扱う

2-1. 準備するもの

この章では次のソフトウェアが必要です。

  • ティラノスクリプトのプロジェクトを起動できるツール(ティラノライダー等)
  • 適当なテキストエディタ

2-2. プロジェクトにモデルを追加する

デフォルトでは「ハル」「エプシロン」という2名のサンプルモデルが組み込まれています。
ここに自分のモデルを追加してみましょう。
さしあたって、ティラノスクリプト公式Live2Dモデル「あかね」を組み込んでみます。

「akane_v1/runtime」フォルダを「tyranoscript_v457/data/others/live2d/assets」フォルダにコピーし、
さらに「runtime」フォルダの名前を「akane」に変更しておきます。

  06.png

さらに「tyranoscript_v457/data/others/live2d/Live2dmodel.js」ファイルをエディタで開き、
最後の行に次の記述を加えます。

Live2dmodel.jsの最後の行に追加すべき記述
// Live2Dモデル(akane)
LIVE2D_MODEL['akane'] = {
    "filepath":"data/others/live2d/assets/akane/",
    "modeljson":"akane_v1.model.json"
};

2行目のakaneの部分には、
シナリオファイルで利用するキャラクターのIDを指定します。
半角英数にしておくのが無難でしょう。

3行目のdata/others/live2d/assets/akane/の部分には、
モデルのデータが入っているフォルダのパスを指定します。

4行目のakane_v1.model.jsonの部分には、
3行目で指定したフォルダ内に存在するLive2DモデルのJSONファイル名を指定します。

最終的に「Live2dmodel.js」ファイル内の記述が次のようになっているか、確認してください。

Live2dmodel.js
// プリロードするモーショングループ
// (尺が長いモーションは事前ロードするのでmodel.jsonのidleグループに入れて下さい)
var PRELOAD_GROUP = "idle";

// Live2Dモデルの配列
var LIVE2D_MODEL = [];

// Live2Dモデル(haru)
LIVE2D_MODEL['haru'] = {
    "filepath":"data/others/live2d/assets/haru/",
    "modeljson":"haru.model.json"
};

// Live2Dモデル(Epsilon2.1)
LIVE2D_MODEL['Epsilon'] = {
    "filepath":"data/others/live2d/assets/Epsilon2.1/",
    "modeljson":"Epsilon2.1.model.json"
};

// Live2Dモデル(akane)
LIVE2D_MODEL['akane'] = {
    "filepath":"data/others/live2d/assets/akane/",
    "modeljson":"akane_v1.model.json"
};

2-3. シナリオ上で表示させてみる

「tyranoscript_v457/data/scenario/scene1.ks」をエディタで開き、
先頭の行に次の記述を追加します。

scene1.ks
; 初期化
[cm]
[clearfix]
[bg storage="room.jpg" time="0"]
[showmenubutton]
[position layer="message0" page="fore" left="20"    top="400"    width="920"  height="200"]
[position layer="message0" page="fore" margint="45" marginl="50" marginr="70" marginb="60"]
[layopt   layer="message0" visible="true"]
[ptext    layer="message0" name="chara_name_area" color="white" size="24" x="50" y="410"]
[chara_config ptext="chara_name_area"]

; Live2Dモデルの定義
[live2d_new  name="akane" left="0" top="0" glscale="1.5"]

; Live2Dモデルの表示
[live2d_show name="akane" time="0" top="-100"]

; 停止
[s]

さて、ここまでできたら、ゲームを起動してみましょう。
ゲームを起動して「はじめから」をタッチすると、次のようなゲーム画面になるはずです。

07.png

[live2d_new name="akane" left="0" top="0" glscale="1.5"]
  Live2Dモデルを定義しています。
  name属性には、「Live2Dmodel.js」で定義しておいたIDを指定します。

[live2d_show name="akane" time="0" top="-100"]
  実際にモデルを表示しています。

補足

モデルを表示した段階で、モデルには自動でアイドリングモーションがついています。
アイドリングモーションというのは、その状態が無限にループ・維持されるモーションのことです。

初期状態のアイドリングモーションがどこで定められているのかというと、
それはモデルのJSONファイル内の記述で決まっています。

akane_v1.model.json
{
    /*...省略...*/
    "motions":{
        "idle":[
            {"file":"motions/akn_idle_01.mtn"}
        ],
    /*...省略...*/

"idle": [ ... ]という記述がありますね。これはJavaScriptの配列を定義しています。
この"idle"配列の先頭に定義されたモーションファイルが、
初期状態のアイドリングモーションになるわけです。

2-4. モーションとエクスプレッションを再生する

さしあたり、モデルは無事に表示することができました。
次にモーション(motion, 動き)やエクスプレッション(expression, 表情)を再生してみましょう。
「scene1.ks」の先頭を次のように書き換えます。

scene1.ks
; 初期化
[cm]
[clearfix]
[bg storage="room.jpg" time="0"]
[showmenubutton]
[position layer="message0" page="fore" left="20"    top="400"    width="920"  height="200"]
[position layer="message0" page="fore" margint="45" marginl="50" marginr="70" marginb="60"]
[layopt   layer="message0" visible="true"]
[ptext    layer="message0" name="chara_name_area" color="white" size="24" x="50" y="410"]
[chara_config ptext="chara_name_area"]

; Live2Dモデルの定義
[live2d_new  name="akane" left="0" top="0" glscale="1.5"]

; Live2Dモデルの表示
[live2d_show name="akane" time="0" top="-100"]

クリックで一度笑います。[p]

; モーションを再生する
[live2d_motion name="akane" filenm="akn_m_01.mtn"]

[wait time="2000"]
クリックでアイドリングモーションを変更します。[p]

; アイドリングモーションを変更する
[live2d_motion name="akane" filenm="akn_m_04.mtn" idle="ON"]

[wait time="2500"]
クリックで表情を変更します。[p]

; 表情を変更する
[live2d_expression name="akane" filenm="f_08"]

[wait time="2000"]
クリックで消します。[p]

; モデルを消す
[live2d_hide name="akane" time="1000"]

; 停止
[s]

[live2d_motion name="akane" filenm="akn_m_01.mtn"]
  モーションの再生を行っています。
  filenm属性には、再生するモーションのファイル名を拡張子付きで指定します。

[live2d_motion name="akane" filenm="akn_m_04.mtn" idle="ON"]
  アイドリングモーションの再生を行っています。
  idle属性にONを指定する必要があります。

[live2d_expression name="akane" filenm="f_08"]
  エクスプレッションの再生を行っています。
  filenm属性には、再生するエクスプレッションのファイル名を拡張子無しで指定します。

[live2d_hide name="akane" time="1000"]
  モデルを消しています。

2-5. その他

その他のタグやガイドラインについては、公式サイトを確認するとよいでしょう。
また、非公式ですがこちらにLive2D関連のタグリファレンスを用意しました。

2-6. おまけマクロ

次のようなマクロを作ると、モデルの操作が楽になると思われます。
JavaScriptに詳しい方は、Switch文ではなく連想配列を用いてデータを取り出す形に書き換えると
よりスマートな記述になると思われます。

scene1.ks
; 初期化
[cm]
[clearfix]
[bg storage="room.jpg" time="0"]
[showmenubutton]
[position layer="message0" page="fore" left="20"    top="400"    width="920"  height="200"]
[position layer="message0" page="fore" margint="45" marginl="50" marginr="70" marginb="60"]
[layopt   layer="message0" visible="true"]
[ptext    layer="message0" name="chara_name_area" color="white" size="24" x="50" y="410"]
[chara_config ptext="chara_name_area"]

; Live2Dモデルの定義
[live2d_new  name="akane" left="0" top="0" glscale="1.5"]

; Live2Dモデルの表示
[live2d_show name="akane" time="0" top="-100"]

; マクロの定義
[macro name="akane_motion"]
    [iscript]
        tf.m = tf.e = true;
        switch (mp.m) {
        case "通常"    : mp.m = "akn_idle_01.mtn"; break;
        case "笑う"    : mp.m = "akn_m_01.mtn"; break;
        case "怒る"    : mp.m = "akn_m_02.mtn"; break;
        case "悲しむ"  : mp.m = "akn_m_03.mtn"; break;
        case "驚く"    : mp.m = "akn_m_04.mtn"; break;
        case "首を振る": mp.m = "akn_m_05.mtn"; break;
        case "頷く"    : mp.m = "akn_m_06.mtn"; break;
        default        : tf.m = false;
        };
        switch (mp.e) {
        case "通常"  : mp.e = "f_01"; break;
        case "無表情": mp.e = "f_02"; break;
        case "怒る"  : mp.e = "f_03"; break;
        case "悲しむ": mp.e = "f_04"; break;
        case "笑う"  : mp.e = "f_05"; break;
        case "驚く"  : mp.e = "f_06"; break;
        case "照れる": mp.e = "f_07"; break;
        case "呆れる": mp.e = "f_08"; break;
        default        : tf.e = false;
        };
    [endscript]
    [live2d_expression cond="tf.e===true" name="akane" filenm="%e"]
    [live2d_motion     cond="tf.m===true" name="akane" filenm="%m" idle="%idle"]
[endmacro]

; マクロを利用してモーション再生
[akane_motion m="驚く"     e="照れる" idle="ON"][l]
[akane_motion m="通常"                idle="ON"]
[akane_motion m="首を振る" e="呆れる"          ][l]
[akane_motion m="頷く"     e="通常"            ][l]
[akane_motion m="笑う"     e="笑う"            ][l]

; 停止
[s]