見出し画像

ビー祭 冬2023 1日目 第三部 しょしんしゃさんの演目技術メモ?

・ご挨拶

こんにちは、しょーちゃんのパパです。うちのこ可愛いですよね。パパもそう思います。
そんなかわいいかわいいしょーちゃんを主役にした映像を後世に残さないのは世界の不幸だよなぁ~~~と常々考えています。

そうして出来上がったのがこちらの動画です。ビー祭本番ではライブで挑んだ結果、トラブルで中断の憂き目にあいましたが、全てビートセイバー内、ひとつの譜面で完結しています。一切の映像加工・編集を行っていません。
なんでもできちゃいますね。懐の深い、楽しくもあり恐ろしいゲームです。  

さて、ここではこの譜面がどうやって作られていったのか……は長くなるので別ページで。(恥ずかしいから有料です。特に見なくて問題ありません)

何をしてこうなったか、肝の部分だけを抽出、メモとして残していきたいと思います。
方向性はどうあれ、Beat Saberで変なことをしてみたい方の参考になれば幸いです。
なお、今回はじめての試みで触った機能ばかりなので、かなり非効率で強引なことをしていますがご了承ください。また、細かい使い方などは書いていません。

・Audacity

音声ファイル編集ツール。
いつもは譜面作成で無音を置いたりすることが主ですが今回は、
・音声収録
・音声加工
・音量調整
・切ったり張ったり
・カット音を乗せてみたり
・ある場面において現在何秒・何フレームかの確認
と、広く活躍してくれました。
ゲーム内効果音は0で、カット音はBGMに乗せていました。
本当はドットノーツ戦のところもSEを入れたかったのですが諸事情で断念。
また、今回のような長尺で演出を重ねていくような表現には、何フレーム目にどんな音がなっているかの確認に最後まで重宝しました。使い方が間違っている気がしなくもありません。

・Chromapper

譜面作りのマストツール。
今回の使い方の主は、NoodleExtensionsの細かい修正に使ったり、何Beat目にイベントを起こすかの確認など。
また、後述のScuffedWallsでノーツを置く場合、ドットノーツが置けないみたいなので、最後の仕上げにも。
CameraScriptを作る時にも重宝しますが、実は今回のカメラはこれで作ってるわけではないんですよね。
このツールの使い方はリュナンさんが紹介しているので、そちらをご参照ください。便利なプラグインも公開してくれてるよ。いつもお世話になっていますありがとうありがとう。

・ScuffedWalls

今回の肝のひとつ、NoodleExtensionsが簡単に制御できるツールです。
mikuriさんが解説ノートを作ってくれているのでご参照ください。

このツールが一番の問題児で一番の功労者でした。
自分で触ってみて改めて、そして初めてわかりましたが、想像以上に底知れない潜在能力を持っています。譜面に対する表現としては文字通りナンデモデキチャウ。
深淵なる可能性を持つので、仮に10%も使い方を理解していたらかなりの理解度じゃないでしょうか。
もし使うなら、独学するより分かる人に聞いてください。公式ドキュメントを熟読するだけでは全ての能力を引き出すことは難しいです。
ただ、自分に聞かれても大したことは答えれないので、とりあえず第一歩として日本人マッパーが集うマッピングサーバーに行くといいです。

不慣れ故、命令文の量がバカみたいな長さとなってしまいましたが、より習熟すれば同じ内容が1/10くらいに収まります。恥晒し以外に意義が見出せるかはわかりませんが、実際に使用したファイルも上げておきます。うーん、無駄が多い。

・NalulunaAvatar

なにはともあれアバターを表示させなければ話になりません。
自分はNalulunaAvatarを愛用していますが、使い慣れたものであれば何でも良いかと。
表情制御については、短時間であったり使用する表情の種類が少なければ手動でも頑張れますが、今回は12分という長時間で細かい表情制御が必要だったので、「NalulunaAvatarEvents」という超絶便利機能を使っています。
[時間]を指定して[どの表情][どれくらい維持]するか、だけの簡単な命令文で、初めてでも安心な親切設計。歌わせることもできます(最高)
これを使用することで、20種に近いブレンドシェイプを簡単に制御できました。
NalulunaAvatarEventsについてはNalulunaAvatarのページに使い方が載っていますので、そちらをご参照ください。
なるるなさんには頭が上がりません。いつもありがとうございます。

実際に使った中身の一部。

12分間の表情制御が200行ちょっとで済むのは控えめにいってヤバい。
ただ、現行バージョン(2023/02/19現在)では
BlendShapeの切り替えはどんどん上書きされていくので

{ "_time": 15.0, "_duration": 1.0, "_key": "BlendShape", "_value": "A" },
{ "_time": 15.0, "_duration": 1.0, "_key": "BlendShape", "_value": "mayuge_syakin" },
{ "_time": 15.0, "_duration": 1.0, "_key": "BlendShape", "_value": "eye_kya-" },

この部分とかは、目と眉毛と口を同時に制御しようとしたけれど、実際には最も新しい命令文のみが適用されるということに注意。
表情が破綻しないように重複しないようになっているみたいです。
(もしかしたら知らないだけでできるのかもしれないけど)
ただ、StartSingとBlandShapeは共存できるので、SetBlendShapeSingで口の形を設定してしゃべらせて、目や口以外の動きはBlandShapeで制御することで、それらしくなりました。
前もって複合ブレンドシェイプを用意しておければもっと楽ですね。

・SpaceDrag

グラディウスの場面で使ってた移動方法。
SteamVR側で制御するのでBeatSaberでも扱えるようです。
自分の環境だと初期立ち位置が中心からズレるので、
ゲーム立ち上げ時に立ち位置をリセット→OffsetApplyで初期位置を固定してから、OffsetDragで移動、場面転換の合間にOffsetResetで現在位置を初期位置に戻していました。
アバターの姿勢が崩れたり、極端に前後移動すぎるとノーツの挙動が変わるので注意。

・CustomPlatform

今回のもう一つの肝。背景演出部分。独自の世界観演出には必須。
通常のカスタムプラットフォームは、何かしらのオブジェクトが動くことはあっても場面転換することは中々ないと思います。
でもやってることは意外と簡単で、オブジェクトが動かせるなら場面を構成しているオブジェクトをまるごと動かしてしまえばいいだけの話です。

GameObjectが大本のCustomPlatform
その直下にアニメーション制御させる階層の中に
OP~Ahanまで各場面。OP中の原色背景なんかもここに。
TitleやGAMESTART,endなどは後付けしたオブジェクト。
CanvasとEventSystemはある演出の実装失敗の残骸。MMD_Camera…?
a2l8は確認用アバター、BSS5は確認用BGMです。
GameObject外部に置くことで、CustomPlatform生成時に出力されずに確認だけできます。

このように各場面ごとに纏めておいて、あとはanimationでキーフレームを打つだけの簡単な作業です。
出したい場面のscaleを1に、それ以外の場面は0に、といった具合で表示・非表示を管理。
表示中の場面のposition,rotationを弄れば移動している感を演出できます。
あとは[いつ][どの場面を][どう動かすか]を工夫すればいい感じになるはず。

オブジェクトを動かす(アニメーションさせる)ことについては少しUnityを勉強すればすぐに出来るようになると思います。
嘘です。独学だとちんぷんかんぷんで時間の浪費です。分かる人に聞くのが一番です。
自分は今回の発想のもとでもある、過去ビー祭で動いたり場面転換するプラットフォームを作られていたモロコシさんに聞きました。超絶感謝の極みです。
今は隠居の身だそうなので、なにかあれば自分に聞いてもらえれば分かる範囲で答えたいと思います。しょーちゃんに聞いてもむつかしいことはわかりません。

実際に使ったアニメーションの一例ですが、皆さんはこんなバカなことはしないでください。
後述するやり方でもっと簡単かつ管理しやすく、プレビュー性も高い効率のいいやり方を紹介します。

・SaberFactory / TrickSaber

好きなセイバーを持たせたり、回転させたり投げたりしたいならこの2つのMODを入れるべきです。
SaberFactoryで好きなカスタムセイバーを持つことができます。
TrickSaberはセイバーを高速回転させたり投げたりすることができます。
また、回転速度、投げた時の速度、投げたものが戻ってくるときの速度など、細かく指定できます。また、投げたり回転させてるセイバーにノーツカットさせるかどうかも指定できます。
普通の速度でブーメランのように扱ってもいいし、超速で射出してレーザービームにしてもいいし、激遅にしてセイバーをその場に置く、といったことも可能です。
戻ってくるときの速度が超速の場合、挙動がバグることがあるようですが、製作者であるToni Macaroni氏に尋ねたところ、忘れてたわガハハとのこと。なんなら即時戻りを追加することも可能だよと仰っていたので、今後のアップデートにも期待がかかりますね。
Thanks Toni Macaroni.

・カメラについて

今回の演出では、CameraScriptを使っていません。
なぜなら上記の作り方だとCustomPlatformのアニメーションがゲーム内やChromapperに取り込んだ時、ポーズ状態、開始する時間に関係なくアニメーションの初めから動き続けてしまうからです。
これでは撮影があまりにも難しすぎる、ということで。
Unity内のCameraをそのままCustomPlatformに仕込んでBeatSaberに持っていってしまいましょう。
そうすることでCustomPlatformのアニメーションタイミング調整とカメラ撮影が一括で行えるようになり作業時間も大幅短縮です。
CustomPlatformにカメラを仕込む方法はMapper神であるJoetastic氏に教えていただきました。
この仕込まれたカメラは他cameraMODを乗っ取ることもあるのでその点は要注意です。

それでは仕込み方です。
ターゲットディスプレイが「ディスプレイ1」に設定され、ターゲットアイが「なし(メインディスプレイ)」であることを確認してください。
CameraはCustomPlatform(Script)が入っているGameObjectの中に入れてください。

いじるところは画像の下2項目だけ。意外と簡単!

あとはカメラオブジェクトを選んで撮影位置を決めてキーフレームを打つだけ!イージングも思いのままです。多分。(よくわからず弄ってない)

今回使ったファイルでは、MMD_Cameraという階層の中にCameraをさらに入れていますが、これは教えてもらったときに頂いたゲーム内のフォグをうまいこと表現してくれる的なMODを活用するための手法です。
MMDは一切関係ないけど、なぜかこういう名前でこういう構造にすると動くみたいです。違いがよくわからなくて結局使わないままで構造だけ残ったは内緒。
とはいえ、GameObject内であればどこにカメラを置いても大丈夫そうです。でも1場面1場面にカメラを置く手法は試したことが無いので分かりません。今回は1つのカメラをひたすら使いまわしています。

Chromapperでもこのやり方でもキーフレームの量は変わらない。

ただし、CustamPlatformにカメラを仕込む手法を使う場合は
大きな大きな注意点が3点あります。

ひとつは、CameraPlusのようにアバターやセイバー、ウォールなどの項目ひとつひとつに表示非表示の切り替えはできないということ。VR画面上に映ってるものはすべて表示されるので、見せたくないものがある場合は何らかの工夫が必要です。しょーちゃんはセイバーを持たせたくないシーンはTrickSaberでカメラ外へ飛ばしたり、アバターがカメラ外にいる間にいろいろ調整したりとかしていました。CullingMaskをどうたらこうたらしたらなんとかなるみたいですが、それをするには別途MODを作る必要がありやなしやのようです。

もうひとつは、より注意が必要です。しょーちゃんはここで事故りました。それは、ポーズ中でもプラットフォームは動き続けるということです。つまり、プラットフォーム内に仕込まれたカメラも動き続けます。場面切り替えを行うこともあるなら同様です。なにかしらの理由でポーズが入ると、その分だけ遅延することになります。秒あるいはコンマ単位の表現をする場合には致命的です。取り返しは効かないので、この手法を使う場合は配信よりは録画環境でやったほうが安全です。

最後のひとつは、曲開始時にリトライが必要ということです。
これは後述する、いい感じに同期させる方法を試しても必要でした。
曲のプレイ時、譜面読み込みとカスタムプラットフォームの読み込みでズレが生じるのか、一発で同期がしっかりとれません。
そのため、譜面開始&プラットフォーム読み込み完了後にリトライを挟むことでズレをなくすことができ、同期します。(リトライ時には既に読み込まれたデータを再利用するため)

・CustomPlatformの同期について

さて、これだけでも動くは動きますが、実はこのままだとアニメーションのタイミングがゲーム内で曲と同期しないのでもう一工夫。
GameObject(CustomPlatform(Script)が入っている親オブジェクト)に「Event Manager(Script)」をAdd Componentしてください。
そして「On Level Start」…だと何故かやっぱりズレるので、
自分は「On Blue Light」を使いました。chromapperで0beat目のライト部分全てに青いライトを置いたら(雑)、なんとか同期してくれました。今回はライトのないカスタムプラットフォームだから、どうせ光らないし問題ありません。

なんもわからんけどUnityにおけるアニメーションの基礎部分らしいから頑張った。頑張って。

あとは画像みたいな感じで…?(どうやってたっけ?)
BaseLayer部分はEntryから直にアニメーションへと繋げると同期できないので、一旦なにもない「New State」を挟んだうえで、曲が始まる(0Beat目でライトがONになって切り替わるタイミング)時に、アニメーションするようにしています。

BlueLightOnの項目にはAnimator->SetTriger(String)にしてAnimatorの入っているObjectを入れ込んで(画像の場合だとGameObject(CustamPlatformが入っている)直下の「Anime」Object)うんたらかんたらです。なんか「Parameters」のところと、SetTriggerのところを同じにしてうんちゃらかんちゃら、ややこしいAnimatorをどうのこうのして動かします。(どうやってたっけ?)
以上です。自分でも何言ってるかもう分かってません。

・もっと便利で簡単に作れる方法

さて、ここまでの解説でどんな感じで作ったか、なんとなく理解していただけたと思います。同時に、うっへぇ~~~~面倒くせェ~~~~~とも感じていただけたと思います。
しかも、今回紹介したやり方だけでそのまま作っていくと、きっとこう思います。
これ動きの確認とかするとき、毎回1から確認しなきゃいけないの?
自分は他に手段がないので毎回1から確認しました。序盤はまだいいですが終盤になると1確認につき10分くらいドブにする力業です。その分たくさんチェックできて細かいミスに気づきやすくなるかもしれませんが、おすすめはできません。

というわけでリュナンさん作の便利なMOD「CustomSongTimeEvent」を導入しましょう!

全部これで一括管理できちゃいます。
じゃあなんでわざわざこんな力業をって?それはもう後戻りできない段階まで作ってからの公開だったからだよ坊や。
今後もし、また似たようなことをする場合はこれを使って楽したいと思います。

まだ実際に使ってないのかって?はい。
でも同イベント二日目の出演者である椿さんはこのツールを使用して見事な完成度のパフォーマンスを見せてくれたので間違いはないです。(もちろん、これ以外にもいろいろ工夫しておられます。)

というわけで

いかがだったでしょうか。
楽しんでいただけたり参考にしていただいたり、何かの着想を得てもらえればそれ以上ない喜びです。
今回はNoodleもUnityもなんもわからんマンが試行錯誤しながら作ったので大変効率の悪いやり方ですが、わかるマンの方ならより効率よくキレイに早く、より素晴らしいものができあがると思います。
行きつく先はMOD作成でゲームを破壊して満足するのでしょうが、
とりあえずこのくらいのものなら、少しの知識と工夫でできるよということで。

noteとか普段書かないので、長文乱文誤字脱字もなんのそのですが、
最後まで読んでくれてありがとうございました。

この記事が気に入ったらサポートをしてみませんか?