オイラーの偶像 ゲーム開発

〖Unityゲーム開発#1〗アイドル育成ゲーム『オイラーの偶像 2026』を作り始めた

Unityで新しくゲームを作っています。
タイトルは 『オイラーの偶像 2026』 です。

ジャンルとしては、ざっくり言うと アイドル育成経営恋愛シミュレーションゲーム です。
プレイヤーは事務所側の立場で、アイドルたちの予定を組み、レッスンや配信準備を進め、メッセージで関係を深め、最終的にライブで成果を出していくゲームにしようとしています。

ただ、単純な育成シミュレーションだけではなく、以下の要素を組み合わせる予定です。

  • Unity UIによる事務所運営・予定管理
  • Naninovelによる会話・イベントシーン
  • スマホ風メッセージ画面
  • メッセージから発生するデート予定
  • AudioSourceとDSP時刻を使った音楽同期ライブ
  • 3Dキャラクターを使ったホーム画面・ライブ演出

つまり、作りたいのは
「育成」「会話(恋愛)」「ライブ」がちゃんとつながるアイドルゲーム です。

第1回となる今回は、今週実装した内容をまとめます。

ゲームの基本設計

キャプション:予定管理画面。アイドルを施設に配置して育成・運営していく。 3DモデルはNayuをお借りしています。のちに変えます。

このゲームでは、ターン制で日付が進みます。

プレイヤーは各ターンで、アイドルを施設に配置したり、予定を確認したり、メッセージを読んだりします。
施設には、ダンス練習場、ボイストレーニングルーム、SNS/配信企画室、メンタルケアルームなどがあります。

アイドル側には、歌唱、ダンス、ビジュアル、SNS、メンタルなどの状態があり、それらを伸ばしながらライブに備える構成です。

今週の大きな目標は、単に画面を作ることではありませんでした。
ホーム、メッセージ、予定、Naninovel会話、ライブをゲームの流れとして接続すること が主な作業でした。

今週実装した内容

今週は主に以下を実装しました。

項目内容
Naninovel会話LOG / AUTO / SKIP / HIDE の操作を修復
Naninovel制御Hide後にEscで復帰できるようにした
会話終了判定@choice / @stop の誤判定対策として __script_done を導入
ライブ音楽同期のリズムゲームとして再設計
ライブテストタイトルからライブだけを確認できるLive Onlyモードを追加
メッセージ1ターンで複数人からメッセージが届くようにした
デートメッセージ返信からデート予定を作成
3DキャラRenderTexture上のクリック二重反応を修正
UI文字切れ、重なり、操作不能箇所を修正

ここからは、特に詰まった部分と対応方法をまとめます。

Unity + Naninovelの会話UIを修復した

キャプション:Naninovelで表示している会話シーン。


会話パートには Naninovel を使っています。

Naninovelはノベルゲーム的な演出を作るには便利ですが、今回のように Unity側の育成ゲーム画面からNaninovelを呼び出す構成 にすると、UI管理が少し難しくなります。

今回起きていた問題は以下です。

  • LOGが開けない
  • AUTO / SKIPが効かない
  • HIDEしたあと戻れない
  • 会話ログのCloseが効かない
  • 選択肢待ちなのにUnity側が「会話終了」と判断する

原因のひとつは、会話中にNaninovel標準UIをまとめて非表示にしていたことです。
その結果、出したくないセーブ・ロード系UIだけでなく、必要なControlPanelまで巻き込んでいました。

対応として、Unity側で独自の会話操作オーバーレイを作りました。
LOGAUTOSKIPHIDE のボタンをUnity UIとして出し、内部では IScriptPlayerIBacklogUI を直接操作する形にしています。

また、Naninovelの @choice@stop は注意が必要でした。
選択肢待ちの状態でも、Unity側から見るとスクリプトが止まっているように見えることがあります。

Unity側ではこの値を見て、会話が本当に終わったかどうかを判断します。

UnityとNaninovelを組み合わせていて、
「選択肢が出る前にゲーム画面へ戻ってしまう」
「Hideしたら戻れない」
という場合は、標準UIの非表示範囲と終了判定を見直すのがよさそうです。

ライブを音楽同期のリズムゲームにした

ライブ画面。VI / DA / VO の3レーンをビートに合わせてクリックする。

ライブ画面は、今週一気に作りました。

現在の仕様は、下部に表示された VIDAVO の3つの円を、曲のビートに合わせてクリックするリズムゲームです。
4つ打ちのビートごとに3つすべての円からタイミング円が広がり、どのレーンを叩くかでスコア計算が変わります。

判定は以下のようにしています。

判定時間
PERFECT0.055秒以内
GOOD0.105秒以内
BAD0.165秒以内

さらに、曲ファイルの先頭と最初のキックが一致しない問題もありました。
音源の0秒をそのまま1拍目と考えると、見た目の円と実際の音がズレます。

そこで、LiveBeatTiming で波形からキック位置を探し、曲ごとに firstBeatSecondsbeatGridOffsetSeconds を持たせるようにしました。

リズムゲームでは、見た目の派手さよりも
押したタイミングと音が納得できること
のほうが大事だと感じました。

メッセージからデート予定を作れるようにした

スマホ風メッセージ画面。複数人のスレッド管理に対応した。

メッセージ機能も今週大きく進めました。

以前は、1ターンにつき1人のメッセージだけを扱う構造でした。
今は1ターン内で複数人からメッセージが届くようにし、既読管理も contactId:turnIndex の形に変更しました。

これで、同じターン内でも

  • 由乃は既読
  • 絵空は未読
  • 琴音も未読

のような状態を扱えます。

さらに、メッセージの返信からデート予定を作れるようにしました。

メッセージ返信からデートに誘う選択肢。


メッセージを読む

返信を選ぶ

Date予定をカレンダーに追加

予定日になる

Naninovelでデートシナリオを再生

親愛度・信頼度に反映

返信後、デート予定が追加され、親愛度が変化する。


ここで大事だったのは、デート結果を固定キャラに入れないことです。
最初は由乃に直接加算していましたが、今後ほかのキャラクターにもデートを追加することを考えて、予定の participantIds から対象キャラを取得する形に変更しました。

予定日になるとNaninovelのデートシナリオへ入る。

この実装で、メッセージがただのテキストではなく、予定と親愛度に接続されました。
育成ゲームとしてはかなり重要な部分です。

RenderTexture上の3Dキャラクリックを修正した

ホーム画面やメンバービューアーでは、3DキャラクターをRenderTextureで表示しています。

そこで起きていたのが、
1回クリックしただけなのに反応アニメーションが2回再生される問題 です。

原因は、クリック入力の経路が複数あったことでした。

  • OnPointerDown
  • OnPointerClick
  • RawImage上のbody tap zone
  • 画面座標ベースのhotzone

これらが同じクリックを別々に拾っていました。

対応として、入力を一度消費したら短時間は同じ反応を走らせないデバウンス処理を追加しました。
また、Animatorに対してtriggerとcrossfadeを重ねて投げると二重再生っぽく見えるため、stateが存在する場合は CrossFadeInFixedTime() を優先するようにしています。

UnityでRenderTexture上の3Dキャラをクリックしていて反応が二重になる場合は、入力経路が重複していないかを確認するとよさそうです。

今後やること

今週で、ゲームの基礎的な流れが少し見えてきました。

次に進めたいのは以下です

  • Spineを組み込む
  • 立ち絵のレパートリーを増やす
  • ダンスシーンのあるライブシーンを作る
  • 自前の3Dキャラを作り、実装する
  • イラストを組み込む
  • ゲームとして面白くする(ぼやっとしすぎ)

以上週報でした。

-オイラーの偶像, ゲーム開発