Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
7.8 KiB
7.8 KiB
Tactica 作業メモ
最終更新: 2026-11-01
完了した作業
| コミット | 内容 |
|---|---|
46e5509 |
マス選択の基本: GameMode / PlayerController / 固定カメラ、ホバーのハイライト、クリックで座標をログ出力 |
3a80827 |
マスの選択状態、カメラのグリッド中心への自動配置、FGridMath(座標計算) |
b18c19a |
ユニットの配置、移動範囲の表示、移動の実行 |
41709fd |
NOTES.md の追加 |
f3f0c08 |
ターン制(Player/Enemy)、2アクション制、ダッシュ、HUD |
344e5e2 |
大きいグリッドでカメラが見切れる問題の修正(四隅の投影で距離を計算) |
リモート(origin/main)には 344e5e2 まで反映済み。
現在の構成
論理層(UObject非依存) → データ層 → Actor層 の順に依存する。
- 論理層
FGridMath: セル座標とワールド座標の変換、範囲判定、グリッド中心FGridState: 1マスごとの歩行可否・高さ・占有ユニットIDFGridPathfinder: ダイクストラで到達可能マスを求め、経路を復元する(4方向、コストはGetStepCostで差し替え可)FTurnManager: ターン数と陣営を持つ。OnTurnStarted/OnTurnEndedで通知する。状態は値型のFTurnState(セーブしやすい)FActionRules: アクション種別ごとのコストと可否。Move=1消費、Dash=残り全部(満タンのときだけ可)
- データ層
FUnitStats: 移動力(4)、1ターンの行動ポイント(2)、ダッシュ倍率(2.0)。FTableRowBase継承で、将来DataTableに移せるTurnTypes.h:EFaction(Player/Enemy)、EActionType(Move/Dash)
- Actor層
AGridCell: マスの見た目。色の優先順位は 選択 > ホバー > 移動可能(緑) > ダッシュ可能(橙) > 通常AGridManager: マス生成、FGridStateとFTurnManagerの所有、ユニット生成、占有情報の唯一の更新者。ターン開始時に、その陣営の行動ポイントを回復する。敵ターンの拡張点はRunEnemyTurn()AUnit: シリンダーの見た目、陣営の色(Player=青、Enemy=赤)、行動ポイント。Tickは移動中だけ有効ATacticaCameraPawn: 固定俯瞰カメラ。グリッドの四隅が画面に収まる距離を自動計算するATacticaPlayerController: 入力と状態(Idle/UnitSelected/Moving)。左クリックで選択・移動、Enterでターン終了ATacticaHUD: ターン数・陣営・選択中ユニットの残りアクションを描画する(状態を持たず、毎フレーム読むだけ)ATacticaGameMode:DefaultEngine.iniのGlobalDefaultGameModeで指定。PlayerController / Pawn / HUD をコードで設定
操作とルール
- 左クリック: Playerのユニットを選択 → 緑(通常移動)/橙(ダッシュ)のマスをクリックで移動
- Enter: ターン終了
- 移動は1アクション消費。ダッシュ(移動力の2倍まで)は2アクションを全消費し、満タンのときだけ可
- アクションが0のユニットは、選択できるが範囲は出ない
- Enemyのユニットは、クリックしてもログが出るだけで操作できない
- Playerの全ユニットのアクションが0になると、移動完了後に自動でターン終了
- 敵ターンは仮実装: ログを出し、
EnemyTurnDelay(1秒)待ってPlayerに戻る - 移動中と敵ターン中は、クリックとEnterを受け付けない
- ターン数は、Playerのターンに戻るたびに+1
設計上の決定事項
- マスの判定:
WorldDynamicのオブジェクトタイプに限定したレイ。地形(Landscape)がマスの上面と同じ高さにあり、Visibilityチャンネルだと判定が交互に切り替わったため。 - ハイライトと陣営色:
/Engine/BasicShapes/BasicShapeMaterialの動的マテリアルでColorパラメータを変更する。新規アセットなし。 - 入力:
InputComponent->BindKey(左クリック、Enter)。操作が増えたら、C++でInputActionを実行時生成する方式への移行を検討する。 - ターン管理の置き場所: 純粋C++の
FTurnManagerをAGridManagerが所有する。GameModeやGameStateには置かない(論理を純粋C++に寄せる方針、Actorクラスの追加を避けるため)。 - 占有情報: 移動の開始時に確定させる。見た目は後から追いかける。
- 行動ポイント: 持ち主はユニット(
AUnit::ActionPoints)。消費は移動の開始時、ターン自動終了の判定は移動の完了後。 - ユニットの当たり判定:
NoCollision。マスのクリック判定を邪魔しないため。クリック先のユニットは占有情報から引く。 - 歩行可否: マス生成時に
AGridCell::bIsWalkableをFGridStateへコピーし、以後はFGridStateを正とする。 - 画面表示:
AHUD::DrawText。UMGやデバッグメッセージは使わない。
未確認・既知の注意点
- ターン制・ダッシュ・HUD(
f3f0c08)は、ビルドは通っているが、エディタでの動作確認は未実施。 - 大きいグリッド(8x8)でのカメラ修正(
344e5e2)も、エディタでの確認は未実施。端が切れる場合はCameraPawnのMarginScaleを上げる。 - カメラ距離は
BeginPlayで一度だけ計算する。PIE中にウィンドウの縦横比を変えても再計算されない。 - 初期配置(
GridManager::InitialUnits)は3x3前提の座標。グリッドを広げたら調整が必要。範囲外の座標は配置されず、警告ログが出る。 - 地形とマスの上面が同じ高さ(Z=0)なので、見た目のz-fightingが出る場合は
GridManagerのZを少し上げる。 bIsWalkableを実行中にエディタで変えても、FGridStateに反映されない。- ユニットIDは生成順の連番。セーブ/ロードやDataTable連携を入れる際に見直す。
CLAUDE.mdの「現状」節は古い(次の目標が「マウスでマスを選択」のまま)。CLAUDE.md自体が未追跡(一度もコミットされていない)。- リポジトリには、今回の作業と無関係な
Content/の差分が大量に残っている。コミットには含めていない。 AGridManagerに、生成・ユニット・ターンの窓口が集まってきている。肥大化したら切り出しを検討する。
残りのタスク
直近
- ターン制・ダッシュ・HUDのエディタ動作確認(上記「操作とルール」の各項目、特に自動終了、移動中の入力無視、敵ターン後のアクション回復)
- 8x8グリッドでのカメラ表示の確認
CLAUDE.mdの「現状」を更新し、コミットするか決めるContent/の未コミット差分の扱いを決める(コミットするか、破棄するか)
次の機能(未着手)
- 敵AI(
RunEnemyTurn()に、ユニットごとの行動を差し込む) - 攻撃とダメージ(
EActionTypeにAttackを追加、HPの導入) - 遮蔽・命中率・視線判定
- オーバーウォッチ
将来の拡張(設計では対応可能な構造にしてある)
- ユニットステータスと行動ポイントなどの設定値のDataTable/DataAsset化(
FUnitStatsを行構造体として利用) - 高低差と移動コスト(
FGridCellData::Height、GetStepCostの拡張) - セーブ/ロード(
FTurnState+ 各ユニットの(ID、座標、陣営、行動ポイント)を保存。復元時はFTurnManager::Restoreを使い、通知を発火させない) - 味方ユニットを通り抜ける移動(現状は全ユニットが障害物)
- Enhanced Inputへの移行(操作が増えた場合)