196スタート画面編g:TyranoScriptでLive2Dを表示する……準備をせよ!【美しょゲを作ろう】
ワクチン打ってから3日目、熱は引いたけどまだ若干のダルオモです。恒石涼平です。
だけどそんなの関係ねえとばかりに、今回も美少女ゲーム制作日誌、 #美しょゲを作ろう を進めていくよ!
前回は #TyranoScript にてゲームが動く仕組みを軽く解説しましたが、今回は #Live2D で作ったモデルをゲーム画面に表示するための準備をしていきます。以前書き出したファイルに加えて、裏で作っておいたアニメーションファイルとかも書き出していくよ~
《Live2D側での準備》
◆アニメーションを書き出そう
以前は「Live2Dモデル」を書き出しましたが、これだけでは不十分。ゲーム画面上で思い通りに動かす為に「Live2Dアニメーション」のファイルも書き出す必要があります。
アニメーションの作り方云々は以前の記事で紹介してるので、作る過程は端折って書き出しの部分だけ解説します!
Live2Dアニメーションの画面では、1つのファイル内で複数のアニメーションを作ることが出来ます。それが画面中央の左側にある「シーン」ってやつだね。
このようにやりたい演出や動きをそれぞれシーンで作成していると一括で書き出すことが出来るのだ。
3分クッキングばりに全部アニメーションは作っておいたので、今回はこちらを書き出していきましょう。
書き出しを押すとこのようなウィンドウが表示されます。
多分最初は「選択中のシーンを出力」になってるので、今回は全部書き出したいので「全シーンを出力」に変更。書き出し対象あたりは特に何も弄らなくておk、下部の3行も同様かな。
「リップシンクとまばたきをモーションに焼き込む」は多分両方を自動で記入してくれるんだけど、今回は手で記入してるので必要なし。「コマ打ちを適用」と「イベントを書き出し」はごめんよく分からない。特に問題があったことはないので今は考えないでおこう。
諸々設定したらOKで書き出し。保存するフォルダを適当に作って書き出すと……
今回の場合はこのようにモーションファイルが書き出されました。多いな?
実はLive2Dにはモーションではなく表情を切り替える機能(Expressionという)もあって、今回のデータではそれを表情以外に使おうとしたので名前に「exp_」って付いてます。まあ上手く行かずに断念したので、そこは立ち絵の導入をするときにでも解説しよう!
では書き出したモーションファイルたちを、以前書き出した「Live2Dモデル」のフォルダへと入れてあげましょう。
流石に直接入れるとファイルの無法地帯と化すので「motions」というフォルダを作ってその中に入れました。これで完了……ではなく、ティラノスクリプトで使う場合はもう1個だけ割とややこしい作業をしなければなりません。
◆アニメーションを使えるように設定しよう
モーションを使えるようにする為には、モデルファイル(~~~.model3.jsonのやつ)に「こういうモーションを使うよ!」という旨を記載する必要があります。
なのでまず「startmenu_fix.model3.json」をテキストエディタなどで開いてみると……
{
"Version": 3,
"FileReferences": {
"Moc": "startmenu_fix.moc3",
"Textures": [
"startmenu_fix.16384/texture_00.png"
],
"DisplayInfo": "startmenu_fix.cdi3.json"
},
"Groups": [
{
"Target": "Parameter",
"Name": "EyeBlink",
"Ids": [
"ParamEyeLOpen",
"ParamEyeROpen"
]
},
{
"Target": "Parameter",
"Name": "LipSync",
"Ids": [
"ParamMouthOpenY"
]
}
]
}
このような文章が出てきました。JavaScriptってやつですね、多分。既に頭が痛くなりそうな謎文章ですが、それぞれ日本語で分かりやすく解説してみましょう。
「"Version": 3」はLive2Dのバージョンを表わすもの。でもLive2Dのバージョンは4のはずなんだけど……そこら辺はよく分からん。気にせず行こう!
「"FileReferences": ~~」はLive2Dモデルで使うファイルの指定。このファイルを使いますよーってこと。物理演算を入れて書き出すと「"Physics": 」という表記が増えます。
「"Group": ~~」はLive2D側で「グループ」に指定したもの。今回はグループを作ってないんだけど、自動まばたき&リップシンクもここに記載されてます。使いたくない場合は「"Ids": 」の中身を削除してね。
……とまあこういったことが記載されてるんだけど、モーションを設定するためには項目を増やす必要があります。早速「"Motions": 」という項目を「"FileReferences": 」の中に追加してみましょう。
{
"Version": 3,
"FileReferences": {
"Moc": "startmenu_fix.moc3",
"Textures": [
"startmenu_fix.16384/texture_00.png"
],
"DisplayInfo": "startmenu_fix.cdi3.json",
"Motions": {
},
},
"Groups": [
{
"Target": "Parameter",
"Name": "LipSync",
"Ids": [
"ParamMouthOpenY"
]
},
{
"Target": "Parameter",
"Name": "EyeBlink",
"Ids": [
"ParamEyeLOpen",
"ParamEyeROpen"
]
}
]
}
このような感じで「"DisplayInfo": 」の下に、
"Motions": {
},
という項目を追加しました。
そしたらこの中へと以下のような文章をモーションファイルごとに放り込んでいきます。
……うん、よく分からんよね。めっちゃ簡単に説明しよう。
「"Idle": [ 」はモーションの名前を指定する。待機モーションなので「Idle」にしてるけど正直何でもいい。ジャンプするモーションなら「"Jump": [ 」にするような感じです。
「{"File":"motions/Idle.motion3.json",」は使うモーションファイルを指定。今回はmotionsフォルダに入れてるやつを使うので「motions/」という形でフォルダの中だということを指定しました。
「"FadeInTime": 1, "FadeOutTime":1} 」はその名の通りフェードイン・アウトの時間を指定します。設定してると別のモーションから切り替えた時にパラメータの動きを滑らかに繋いでくれます。時間の単位は分からんが多分、秒。
「 [ 」「 ] 」「 { 」「 } 」とかは配列とか色々ややこしいプログラミング要素なので気にせずそのまま使うだけでOK。複数モーションを設定する場合は「 , 」で区切ることだけ意識しておいてくださいまし。
……簡単にとは言ったもののやっぱ難しいよね。軽くでもJavaScriptの知識があると分かりやすいんだろうけど私もそこまで詳しくないからなー。
なお軽く知りたい場合は「Progate」とかの学習サービスがオススメです。自分はそれでプログラミングの触りを理解出来たので、このLive2D組み込みの辺りで問題が発生しても何とか乗り越えられました。
と余談は置いといて、全てのモーションを記載したスーパー長文ファイルがこちらになります。
{
"Version": 3,
"FileReferences": {
"Moc": "startmenu_fix.moc3",
"Textures": [
"startmenu_fix.16384/texture_00.png"
],
"DisplayInfo": "startmenu_fix.cdi3.json",
"Motions": {
"Idle": [
{"File":"motions/Idle.motion3.json" ,"FadeInTime":1, "FadeOutTime":1}
],
"Intro1": [
{"File": "motions/Intro1.motion3.json", "FadeInTime": 0, "FadeOutTime": 0}
],
"Intro2": [
{"File": "motions/Intro2.motion3.json", "FadeInTime": 0, "FadeOutTime": 0.5}
],
"Scale": [
{"File": "motions/Scale.motion3.json", "FadeInTime": 0, "FadeOutTime": 0}
],
"Test": [
{"File": "motions/Test.motion3.json", "FadeInTime": 0, "FadeOutTime": 0}
],
"Quicktest": [
{"File": "motions/Quicktest.motion3.json", "FadeInTime": 0, "FadeOutTime": 0}
],
"Quicktest_config": [
{"File": "motions/Quicktest_config.motion3.json", "FadeInTime": 0, "FadeOutTime": 0}
],
"Anten": [
{"File": "motions/Anten.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"Stop": [
{"File": "motions/Stop.motion3.json", "FadeInTime": 5, "FadeOutTime": 0}
],
"Config_display": [
{"File": "motions/Config_display.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"Config_displayOff": [
{"File": "motions/Config_displayOff.motion3.json", "FadeInTime": 0.5, "FadeOutTime": 0}
],
"exp_dful": [
{"File": "motions/exp/exp_dful.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_dwin": [
{"File": "motions/exp/exp_dwin.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_leng": [
{"File": "motions/exp/exp_leng.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_ljpn": [
{"File": "motions/exp/exp_ljpn.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_s00": [
{"File": "motions/exp/exp_s00.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_s20": [
{"File": "motions/exp/exp_s20.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_s40": [
{"File": "motions/exp/exp_s40.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_s60": [
{"File": "motions/exp/exp_s60.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_s80": [
{"File": "motions/exp/exp_s80.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_s100": [
{"File": "motions/exp/exp_s100.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_thigh": [
{"File": "motions/exp/exp_thigh.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_tlow": [
{"File": "motions/exp/exp_tlow.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
],
"exp_tmid": [
{"File": "motions/exp/exp_tmid.motion3.json", "FadeInTime": 1, "FadeOutTime": 0}
]
},
},
"Groups": [
{
"Target": "Parameter",
"Name": "LipSync",
"Ids": [
"ParamMouthOpenY"
]
},
{
"Target": "Parameter",
"Name": "EyeBlink",
"Ids": [
"ParamEyeLOpen",
"ParamEyeROpen"
]
}
]
}
うーん地獄。
所々使ってないやつやサイズを設定するためだけに使うためのやつもあるので、そこを削減したらもう少し短くなりそうです。
《おわりに》
長くなったので今回はここまで。ややこしい話ばっかりでごめんね。
しかしこれでLive2Dサイドでの準備は完了したので、次回でようやくゲーム画面に表示出来るはず。タイトル画面1個作るのにもこれだけ大変なんやでぇ……
ではお疲れ様でした。また次回お会いしましょう!
もしも記事が参考になったら、スキやフォローよろしくね! 気が向いた時はサポートで支援していただけると嬉しいです。