【個人ゲーム開発26日目】戦術SLG制作

今日は「操作していて気持ちいい」を追求する日

午前中は、美容院へ行ってきました。
そろそろヘアドネーションできるくらいに髪が伸びまくってます(笑)
色入れてポニテにして帰宅してからの作業となるので午後から開発再開。

今日は戦術シーンの操作性向上を中心に、UI改善・敵AI調整・バグ修正と、 地味だけど確実にゲームの完成度を上げるタスクを集中的に片付けました。

派手な新機能ではないですが、「これがないと遊びにくい」という部分です。 実際に触ってみると操作感が全然違う。こういう積み重ねがゲームの質を決めると思っています。


■ 敵AI行動順の改善

移動力が高いユニットが先に動くようになった

これまで敵ユニットの行動順は移動力の低い順(昇順)でした。 鈍重なユニットが先に動いてしまい、後から高機動ユニットが動こうとしても 道が塞がれている、という状況が発生していました。

本日、行動順を以下のルールに変更しました。

  1. 行動優先度(aiPriority)の高い順
  2. 移動力の高い順
  3. ステージデータのリスト順(SpawnIndex順)

これにより高機動ユニットが先に展開して道を空けてから、 鈍重なユニットが続く、という自然な動きになりました。

StageDataEnemySpawnInfoaiPriorityフィールドを追加したので、 ステージデザイン時に特定のユニットを優先的に動かす制御もできます。 デフォルト値は0で既存ステージへの影響はありません。

基本的に0にして特に先に動かしたいといった戦術的な意味が出た時に使用する予定。


■ ユニット表示順の統一

リスト順・巡回順・表示順がすべて一致するようになった

これまでユニットリストウィンドウの表示順はモデル番号順でした。 後述する右クリックフォーカス巡回を実装するにあたり、 「ステージデータのリスト順」と「ユニットリスト表示順」が一致していないと 直感的に使いにくいと判断して統一しました。

敵・味方ともに生成時にSpawnIndexを連番付与するようにして、 ユニットリストウィンドウの並び順もSpawnIndex順に変更しています。

結果として以下の3つが完全に一致するようになりました。

  • ステージデータ(Inspector)のリスト順
  • ユニットリストウィンドウの表示順
  • 右クリックフォーカスの巡回順

■ 右クリックで未行動ユニットへフォーカス

ユニットを探し回らなくてよくなった

ターン制SLGで地味にストレスなのが、「あれ、まだ動いてないユニットどこだっけ」です。 マップをスクロールして探すのは手間です。

本日、右クリックの短押しで未行動ユニットへ自動フォーカスする機能を実装しました。

仕様は以下の通りです。

  • 短押し判定:押下から0.2秒以内、かつマウス移動量5px以下
  • 初回:現在のカメラ位置に最も近い未行動ユニットへ
  • 2回目以降:SpawnIndex順に巡回(末尾まで行ったら先頭に戻る)
  • 左クリックするとインデックスがリセットされ、次の右クリックで近いユニットから再スタート

カメラ移動は瞬間移動にしています。 なめらかなスクロール移動は敵AIの行動確認には便利ですが、 自分でユニットを探す際はテンポが悪い。用途で使い分けています。

また画面内に十分収まっているユニットへのフォーカスはカメラを動かさず、 グリッドカーソルだけを飛ばす仕様にしました。 マップ表示エリアの10%マージン内に収まっていればカメラ移動なしです。


■ 右クリックでターン終了(確認ダイアログ)

全ユニット行動済みなら右クリックでターンを終える

右クリックフォーカスの自然な拡張として、 未行動ユニットがゼロになった状態で右クリックするとターン終了確認ダイアログが表示されるようにしました。

「巡回するユニットがなくなった=全員行動済み=ターン終了の意思」という流れが 右クリックだけで完結します。

あわせてターン終了ボタンも確認ダイアログを経由するように変更しました。 未行動ユニットの有無でメッセージが分岐します。

  • 未行動ユニットあり:「未行動のユニットがいます。ターンを終了しますか?」
  • 未行動ユニットなし:「ターンを終了しますか?」

テスト中に「うっかりターン終了ボタンを押してしまう」ことが何度かあったので、 この確認ステップは実用上かなり助かります。 3言語対応済みです。

とりあえず英語版です。


■ 敵ユニットホバーで移動・攻撃範囲表示

敵の脅威範囲が一目でわかるようになった

敵ユニットにマウスを0.3秒ホバーすると、移動範囲と攻撃範囲がハイライト表示される機能を実装しました。

表示内容はユニットの特性によって変わります。

  • 移動後攻撃可能なユニット(戦車・装甲車など):移動範囲(青)+移動範囲外の攻撃範囲(赤)
  • 移動後攻撃不可のユニット(野砲・自走砲・駆逐戦車など):現在地からの攻撃範囲(赤)+移動範囲(青)

野砲など射程の長いユニットの脅威範囲は広く、 「ここに入ると即攻撃される」という判断をプレイヤーが事前にできるようになりました。 特に高機動・長射程ユニットの把握が格段に楽になっています。

0.3秒の遅延を入れているのはカーソルを動かすたびに表示が切り替わる 「うるさい」状態を避けるためです。

これないと高機動ユニットや長距離砲の範囲がわかりにくいので慌てて実装という感じです。詰将棋的なマップをいずれ作る予定なのでちまちまマス目数えてらんないかなと。


■ ズームボタン・倍率表示のデザイン更新

長年の「芋ボタン」がついに卒業

ずっと仮置きのプレーンなボタンだったズームボタンと倍率表示をデザインしました。

「+」「-」ボタンはメタル感のある画像に差し替え、 倍率表示は7セグメント風のデジタルフォントスタイルに変更しています。 サイドパネルの世界観と統一感が出ました。


■ グリッドカーソル消失バグの修正

地味だけど気になっていた問題が解消

ランダム配置される特定の地形チップ上でグリッドカーソルが見えなくなる現象がありました。 条件が不定で再現性が低く、ずっと原因不明でした。

調査した結果、GridCursorObjectのレイヤー順序が0になっており、 特定のタイルチップの下に隠れてしまっていたことが原因でした。

レイヤー順序を0から4に変更して解消しています。 ユニット(1〜3)より前面、UIウィンドウ(4〜10)と同レベルに設定しました。


■ シーン完成状況

シーン状況
タイトル✅ 完成
ブリーフィング✅ 完成
戦術(メインゲームプレイ)🔧 実装中
結果✅ 完成
エンディング✅ ほぼ完成

執筆後記
今日は地味な日でした。でも地味な改善が一番大事だと思っています。
特に右クリックフォーカス→巡回→ターン終了という一連の流れが繋がったのは大きいです。 キーボードに手を伸ばさず、右クリックだけでターン管理ができる。 操作の流れがスムーズになると、ゲームに集中できます。
実装中に「右クリック処理を複数のスクリプトで監視してはいけない」という教訓を得ました。 CameraControllerCursorManagerの両方が右クリックを監視していたせいで、 しばらくバグに苦しめられました。入力の一元管理は徹底します。
また本日Xの青バッジを取得しました。 今後は開発進捗の発信も積極的にやっていきます。 完成度が上がってきたので、プレイ動画などもそろそろ出せるかなと思っています。