- 1. 今回の実装目的と解決した課題
- 2. 開発の背景と設計思想 (Why & How)
- 3. 実装と修正の詳細 (Technical Diff)
- 4. トラブルシューティング
- 5. 未来の自分へ:次回実装時のテンプレート(標準手順)
- 🇺🇸 [English Version]
- 1. Objective and Problem Solved
- 2. Design Philosophy (Why & How)
- 3. Implementation Details (Technical Diff) [DO NOT SUMMARIZE]
- 4. Troubleshooting
- 5. Template for Future Implementation
1. 今回の実装目的と解決した課題
Flexible Combat System (FCS) の設計思想に基づき、ダンジョン入口UIからの「出発ボタン」押下によるダンジョン生成と、全プレイヤーのワープ・暗転処理を同期させるシステムを構築しました。
ホストとクライアント間でのUI表示の残りや、座標同期の失敗による「座標の巻き戻し」が発生しましたが、今回はFCSのUI管理ルールに従いつつ、信頼性の高い「ハンドシェイク(同期)」処理を実現しました。
2. 開発の背景と設計思想 (Why & How)
FCS環境で最も注意すべきは「循環参照によるエディタの破損」と「通信の確実性」です。
- 循環参照の回避: UIクラスをPCで直接保持せず、
User Widget(親クラス)として保持することで、ビルド時や起動時のインターフェース破損を防ぎます。 - 責務分離の徹底: UIはインターフェース経由でPC(Controller)に依頼を投げるだけで、直接PCのロジックを叩かない設計にしました。
- 通信の信頼性: 座標更新には
SetActorLocationを直接使わず、Reliable RPCを介した強制テレポートを採用しました。
3. 実装と修正の詳細 (Technical Diff)
- BP_PlayerController
- 対象の関数/イベント:
CreateWidgets,IsWidgetOpen,Event ToggleDungeonEntranceUI,Server_RequestStartDungeon,Client_ExecuteWarp - 追加・変更した変数:
WBP_DungeonEntrance_Ref(User Widget型) - 実装内容:
WBP_DungeonEntranceを事前生成し、汎用的なUser Widget型で保持する。特定のUIクラス(WBP_DungeonEntrance)で変数を保持すると、PCとUIの間で循環参照が起き、エディタ起動時にインターフェースが破損するため、必ず汎用の親クラス(User Widget)で保持する。Client_ExecuteWarp(Run On Owning Client / Reliable) を実装し、サーバーからの強制ワープを実行。bTeleport = Trueを使用して物理補正を無効化。


- BP_MyGameState
- 対象の関数/イベント:
Server_RequestNextFloor,Server_OnPlayerFinishedBuilding,Server_CompleteDungeonGeneration - 追加した変数:
ReadyPlayersCount(Int),BuildTimeoutHandle(Timer Handle) - 実装内容:
ReadyPlayersCountで完了報告をカウントし、全員揃った瞬間にワープと暗転解除を命令。- フリーズ対策として10秒のタイムアウトタイマーを実装。


- WBP_DungeonEntrance (UI)
- 対象の関数/イベント:
Btn_Depart_OnClicked,SetGamepadFocus - 実装内容:
- ボタン押下時にインターフェース経由でPCへ依頼。
- 画面表示直後に0.05秒のDelayを挟み
SetFocusすることで、ゲームパッドでの決定ボタン操作に対応。
4. トラブルシューティング
- 不具合: クライアントがロード中に暗転が戻らない。
- 解決策: ウィジェットの多重生成が起こっていたため、
ToggleLoadingScreenにIs Validチェックを追加し、ウィジェットの多重生成を阻止。また、Run Phaseの変更直後にDelay (0.5s)を入れ、1フレーム通信による状態変化の取りこぼしを物理的に回避しました。
5. 未来の自分へ:次回実装時のテンプレート(標準手順)
新しいUIを追加する際の標準フローを定義しました。
5-1. E_WidgetUI(Enum)
- 追加: Enum要素 DungeonEntrance
- 目的: IsWidgetOpen / ToggleWidgets が扱うUI識別子への追加。
5-2. I_PlayerController(Interface)
- 追加関数: ToggleDungeonEntranceUI, RequestDungeonStart_Interface
- 目的: FCS標準のUI管理フローへの準拠と、UIとPCの疎結合化。
5-3. BP_PlayerController(最重要実装)
- 変数: WBP_DungeonEntrance_Ref (Object Reference: User Widget)
- ※汎用親クラス保持により、特定のWidgetクラスとの循環参照を回避。
- 関数: CreateWidgets:
- 事前生成し、FCS既存の WidgetList 処理や Collapsed 設定の「前段」で登録を実行。
- 関数: Is Widget Open: DungeonEntrance 分岐を追加。
- イベント: ToggleDungeonEntranceUI: FCS標準テンプレ(Adjust Input Mode → ToggleWidgets)で実装。
- RPCの実装:
- Server_RequestStartDungeon (Run On Server / Reliable): サーバーへ開始要求を送信。
- Client_ExecuteWarp (Run On Owning Client / Reliable): 強制テレポート。bTeleport = True で物理補正を無効化。
- Server_NotifyDungeonBuilt (Run On Server / Reliable): クライアントの地形生成完了報告。
- 暗転ロード運用ルール:
- クライアント自律型の RunPhase (RepNotify) 管理。
- Listen Server(ホスト)は自身の OnRep が発火しないため、サーバー処理直後に手動で暗転を制御。
- ToggleLoadingScreen 内で Is Valid チェックを徹底し、暗転の多重生成を阻止。
5-4. BP_PlayerCharacter(Interact)
- Interact処理: 既存の Combat Interact 前段に IsValid(CurrentEntrance) を追加。該当時のみ ToggleDungeonEntranceUI を実行。
5-5. BP_DungeonEntrance
- UI生成責務を削除。すべてPlayerControllerへ集約。
5-6. WBP_DungeonEntrance(UI)
- Btn_Depart (OnClicked): 「UIを閉じる」→「Interface依頼送信」の順序を厳守
- Gamepad対応: 表示直後に0.05秒のDelayを挟み SetFocus。
5-7. BP_MyGameState
- サーバー制御: Server_RequestNextFloor はNot Replicatedに変更し、制御を BP_PlayerController に集約。
- ハンドシェイク変数: ReadyPlayersCount (カウント用), BuildTimeoutHandle (15秒タイムアウト用)。
🇺🇸 [English Version]
※ English version below.
※ The English text is AI-translated from the original Japanese article.
🇺🇸 [English Version]UE5 + FCS: Implementing Robust UI and Synchronized Dungeon Transitions
1. Objective and Problem Solved
We have built a dungeon transition system compliant with the Flexible Combat System (FCS) architecture. The goal was to ensure synchronized dungeon generation, player warping, and screen fading across all clients when a “Depart” button is clicked. We addressed issues such as lingering UI elements and coordinate synchronization failures (rubber-banding) by implementing a robust handshake mechanism.
2. Design Philosophy (Why & How)
The key focus in an FCS environment is avoiding “Circular References” and ensuring “Communication Reliability.”
- Avoiding Circular References: We hold UI references as
User Widget(base class) rather than specific types within the PlayerController to prevent editor crashes/interface corruption. - Strict MVC: UI (View) communicates with the PlayerController (Controller) solely through interfaces, maintaining loose coupling.
- Reliable Communication: We implemented
Reliable RPCsfor teleportation, ensuring packets are received and ignoring physics displacement during warp.
3. Implementation Details (Technical Diff) [DO NOT SUMMARIZE]
- BP_PlayerController
- Target Function/Event:
CreateWidgets,IsWidgetOpen,Server_RequestStartDungeon,Client_ExecuteWarp - Variables Added/Modified:
WBP_DungeonEntrance_Ref(User Widget Object Reference) - Details:
- Pre-generated the widget and stored it as a generic
User Widgetto avoid circular references. - Implemented
Client_ExecuteWarp(Run On Owning Client / Reliable) to execute force-teleportation on clients, usingbTeleport = Trueto bypass physics interference.
- Pre-generated the widget and stored it as a generic
📸 [Insert image of BP_PlayerController RPC setup here]
- BP_MyGameState
- Target Function/Event:
Server_RequestNextFloor,Server_OnPlayerFinishedBuilding,Server_CompleteDungeonGeneration - Variables Added/Modified:
ReadyPlayersCount(Integer),BuildTimeoutHandle(Timer Handle) - Details:
- Managed completion reports via
ReadyPlayersCount. Triggered warp and screen clear only when all clients report success. - Implemented a 15-second timeout fail-safe to handle player freezes.
- Managed completion reports via
📸 [Insert image of Server_CompleteDungeonGeneration and Timer Control here]
- WBP_DungeonEntrance (UI)
- Target Function/Event:
Btn_Depart_OnClicked,SetGamepadFocus - Details:
- Emitted interface requests to PC upon button click.
- Implemented a slight Delay (0.05s) before
SetFocusupon UI display to ensure gamepad compatibility.
4. Troubleshooting
- Issue: Clients stuck in black screen due to failure in screen fade toggle, or multi-generation freezes.
- Fix: Added
Is Validchecks toToggleLoadingScreento prevent multiple overlapping widgets. Inserted aDelay (0.5s)immediately after changingRun Phaseto prevent “1-frame communication loss” where state changes are ignored by clients.
5. Template for Future Implementation
Follow this standard flow for adding new UI within the FCS framework:
- Enum: Add to
E_WidgetUI. - PC Interface: Register
ToggleYourWidgetUIinI_PlayerController. - Pre-generation: Generate in
CreateWidgetsusingUser Widgettype. - Check: Add branching logic in
IsWidgetOpen. - Toggle: Use standard FCS toggle event pattern.
- Focus: Implement micro-delay +
SetFocusfor gamepad support. - Request: UI button clicks must only use Interface messages (No direct casting to PC).

