やっとNaninovelになれてきた
前回記事が5月末で、それからティアキンが挟まり、8月半ばという感じです。だいぶ開きました。ティアキンはだいたい三週間くらいでクリアしたので、色々NaninovelとUnityのほうで試行錯誤していました。
前回ポストエフェクトを実装しましたが、ゲーム中にスクリプトのコマンドで簡単にポストエフェクトの程度を切り替えたりできないかな、と思って一ヶ月ほど弄ってました。結構どうにかなりそうでならなかったので、一旦深追いせずできそうな方を優先して、予定していた口パク とカスタムプリンター の方を実装しました。
見ての通り、平野さんのグラフィックはみるきさんの方で試行錯誤され、今回のもので行くことになっています。かわいいですね。教室の背景やカスタムプリンターの画像もみるきさんが作成しました。
また、しばらくずっとNaninovelの配布しているデモデータで試していたんですが、新しく『まほだん』本編用のプロジェクトを作成して、データを作りはじめました。やっとって感じですね!
あとはシナリオを何度か読み直しして、プロット作りの手伝いとかもしたり。シナリオの方の記事も追って上がるみたいです。
今回は、公式のマニュアルでは情報が省略されている口パクについて詳細に解説していきます。(カスタムプリンターについては手厚いので、あまり難しいことはありませんでした。どちらかというとPrefabについて触ることになるので、Unityサイドの話になります)
口パク
目的 ―― 喋ってるときに口を動かしたい!
というわけで口パクです。
該当キャラクターが喋っているとき、キャラクターの口が動く機能ですね。
ゲームってとにかく手触り (ボタンを押したときにいい感じに音や画面が動いたりする)が大事だと思うんですが、アクションゲームならともかく、ノベルゲームで手触りをよくできる部分って限られます。口パクはキャラクター表現を豊かにするだけじゃなくて、手触りにも大きく寄与する部分だと思います。
なので口パク、実装しました。
口パクの構造 ―― アニメーションを喋るタイミングで呼び出す
Naninovelではキャラクターのタイプがいくつかある、というのをポストエフェクトのときにも書いたんですが、口パクに対応してるタイプが限られます。現在のNaninovel日本語ドキュメントでは、[一般キャラクター]https://naninovel.com/ja/guide/characters.html#一般キャラクター )(一般キャラクター、と書いてあるけれど、英語だとgeneric characterで、設定的には一番詳細に設定する方法、という感じです)、Live2Dのキャラクターに対応していると書いてありますが、英語のドキュメントではLayerdCharacterにも対応している と書いてあります。
今回はLayerdCharacterで実装していくので、その方法を書いていこうかと思います。ちなみに口パクの設定方法について、Naninovelのドキュメントではあんまりフォローしていないです。
>一般キャラクターで口パク機能を利用するには、 CharacterActorBehaviour コンポーネントの On Started Speaking と On Finished Speaking Unityイベントを使用してください。そのキャラクターが表示メッセージを話始める時(またはメッセージが完全に表示された時)イベントが呼び出され、そのキャラクターの口パクアニメーションの開始や停止などのカスタムロジックをトリガーできます。これはUIの On Show イベントと On Hide イベントの仕組みに似ています。 UIカスタマイズガイドでカスタムアニメーションの駆動に使用する方法を見つけてください。
やってみるとおおよそこの通りなのですが、Unity初心者の私には大変でした。具体的な実装方法は、カスタムUI にある解説動画が一番参考になりました。
Naninovelの口パクは、喋るタイミングでアニメーションを呼び出し、また喋り終わるタイミングでアニメーションを止める、という形で実装されます。アニメーション自体はNaninovelではなく、UnityのAnimatorによって実装 され、NaninovelはしかるべきタイミングでAnimatorにトリガー を投げ込んで、状況を遷移 させるという形です。なのでまずはアニメーションのデータを作る必要があります。
Animation Clipの作成
幸い、UnityのAnimatorについての記事はネットにもいっぱいあります。
私が手始めに参考にしたのは
【Unity】Animator機能のことはじめhttps://note.com/info_/n/n577f4f3147ec
です。
この記事の通り、とりあえずアニメーションウィンドウでクリップを作成します。この際、アニメーションさせるキャラクターのPrefabを開き、選択した状態にしましょう。prefabを開いていないとボタンが押せません。(初心者のうちはこういう何でもないところで結構躓いて、時間がとられますよね)
そうして作成したAnimation Clipに、Add Property でアニメーションさせるものを追加します。
こんな感じで、追加できるプロパティがめちゃめちゃ多くてろたえるのですが、
prefabの中から口パクさせたい口があるレイヤーを探し、そのscale を追加します。
(口パクの際に位置も変えるなら、positonも追加する必要があるでしょう)
追加したら、いい感じにアニメーションを作ってください。
実際にキャラクターを口パクさせて、動きを確認しながら実装できるので結構楽しいです。こんな感じで実装されてます。
この際、色々な表情の口それぞれに口パクを実装しています。
ちなみにアニメーションでscaleを変更する方法以外に、Spriteの画像を切り替える方法でも試したのですが、prefabの動作ではちゃんと機能するものの、Naninovelで実際に動かしてみると機能しませんでした。
Animator Controllerの作成
上の記事にもある通り、アニメーションの遷移を管理するものです。ステートマシンですね。
こんな感じで、初期状態(init)と喋っている状態(speaking)、喋っていない状態(wait)を作り、transition(遷移する矢印)で結んでいます。スクショで選択しているspeakingに、先程作成したclipがMotionで紐付けます。waitとinitはnoneのままです。
この際、initとwaitのSpeedは高く設定してください。(私は10000)にしています。この値が低いと、口パクに切り替わるタイミングが遅れて、短い台詞だと口パクしなくなったりします。
あとは、遷移する条件を設定する必要があります。paramaterの+からTriggerを選択し、喋りはじめのトリガー(Started Speaking)と喋りおわりのトリガー(Finished Speaking)を追加します。トリガー名は任意です。
Naninovelの設定をしたら口パク完成!
重要なのは、
Layered Character BehaviourコンポーネントのAnimated をTrue
Layered Character BehaviourコンポーネントのOn Started Speaking()とOn Finished Speaking()にトリガーを設定
AnimatorコンポーネントのControllerに↑で作成したAnimator Controllerを設定
です。
少し複雑なのはOn Started Speaking()とOn Finished Speaking()の設定。しゃべりはじめたときとしゃべり終えたときにこの関数が呼び出されるようです。ここで影響を与えるObjectを選択する必要があり、
Animatorをドラッグして選択します。
そのうえで、Animator.SetTriggerとAnimator.ResetTriggerに、↑で追加したトリガー名を追加します。お分かりだとおもいますが、しゃべりはじめたときにStarted Speakingをセットし、Finished Speakingをリセットします。しゃべりおわりはその逆です。
というわけで、口パクの完成です! やったー。
ついでにしゃべるときのSEとか
記事冒頭の動画では、しゃべりに合わせてぴろぴろと鳴っていますが、これについては全く別の設定です。また、しゃべっていないときにグレーがかって、しゃべっているときに明るく強調されるのも同様です。
どちらもNaninovelのConfiguration内のCharactersで設定します。
音声データをAudioのほうでNaninovelに登録すると、Message Soundで選択できます。
強調については強調されていないとき(wait)と、強調しているとき(highlight)の効果を、Poseの項目で設定します。そのうえで、Highlight When Speakingをtrueにし、設定したPose NameをSpeaking PoseとNot Speaking Poseに設定すればオッケーです。
というわけで、今回は口パクの記事でした。次はカットインとか、UIとか、独自のミニゲーム的な部分について触っていこうと考えています。が、5日後にはアーマード・コア6が発売してしまうので、またその分遅れると思います!
では!