Espelho simétrico do front-end pattern (UUIFrontEndFlowSubsystem +
DA_FrontEndScreenSet + UUIPrimaryGameLayout_Base) para a UI in-game.
Pavimenta caminho pra Inventory, Skills, StatusWindow, EscapeMenu, etc.
## UI in-game system (Source/ZMMO/Game/UI/InGame/)
- EZMMOInGameUIState enum (None, Playing, StatusWindow, Inventory,
SkillTree, EscapeMenu, Loading) em Data/UI/InGameTypes.h
- UUIInGameScreenSet DataAsset: TMap<EZMMOInGameUIState, TSoftClassPtr<...>>
- UUIInGameFlowSubsystem (GameInstanceSubsystem) com SetState/ToggleScreen
- DA_InGameScreenSet em Content/ZMMO/UI/InGame/ mapeia Playing->WBP_HUD
- Layer routing: Playing -> UI.Layer.Game | menus -> GameMenu | loading -> Modal
## AHUD pattern (idiomatic UE5)
- AZMMOHUD : AHUD em Source/ZMMO/Game/Modes/
- AZMMOGameMode::HUDClass = AZMMOHUD::StaticClass()
- AZMMOHUD::BeginPlay chama UIInGameFlowSubsystem::StartInGame
- Pawn não cria mais HUD (separação de responsabilidades)
## PlayerState + Component Registry (Open-Closed)
- AZMMOPlayerState : APlayerState em Source/ZMMO/Game/Modes/
- AZMMOGameMode::PlayerStateClass = AZMMOPlayerState::StaticClass()
- UPROPERTY Config TArray<TSubclassOf<UActorComponent>> ComponentClasses
- DefaultGame.ini: +ComponentClasses=/Script/ZMMOAttributes.ZMMOAttributeComponent
- Ctor lê via GConfig (mais robusto que UPROPERTY Config + parsing) e
instancia cada componente como CreateDefaultSubobject
Por que componentes no PlayerState e não no Pawn:
- Sobrevive ao despawn (morte/respawn)
- Spectator-friendly
- 1:1 com player (Pawn pode trocar: vehicle, mount, possession)
- Padrão MMO clássico (rathena, TrinityCore)
Adicionar novo módulo (Inventory, Skills, Guild) = 1 linha no
DefaultGame.ini, sem editar AZMMOPlayerState.cpp.
## HUD composite
- UZMMOHudWidget : UCommonActivatableWidget em ZMMO core (UI/InGame/)
- WBP_HUD em Content/ZMMO/UI/HUD/ herda UZMMOHudWidget
- HpSpBar (UZMMOHudHpSpWidget — sub-modulo ZMMOAttributes) embedded via
BindWidgetOptional. Sub-widgets futuros: PlayerInfo, Minimap, QuickBar,
Buffs, Chat, TargetInfo
- UZMMOHudHpSpWidget volta a ser UUserWidget puro (sub-widget, não root)
- UZMMOHudWidget::NativeOnActivated:
- SetVisibility(HitTestInvisible) — mouse passa direto pro Pawn
- BindToLocalPlayer: busca AttributeComponent no PC->PlayerState
- Subscreve OnAttributesChanged/OnHpSpChanged/OnLevelUp
- Propaga snapshots pra sub-widgets via HpSpBar->ApplySnapshot
- GetDesiredInputConfig override: ECommonInputMode::Game (sem cursor,
movimento livre). Menus override pra GameAndMenu/Menu.
## NetworkHandler refatorado (AttributeComponent agora no PlayerState)
- ZMMOAttributeNetworkHandler::FindComponentForEntity: busca via
GameState->PlayerArray (O(N_players)), não TActorIterator (O(N_actors))
- ZMMOAttributes.Build.cs += CommonUI, CommonInput
## EnsureRootLayout (fix crítico)
- OpenLevel invalida widgets no viewport ("InvalidateAllWidgets")
- RootLayout (criado pelo FrontEndFlow no boot) sobrevive como UObject
(LocalPlayerSubsystem) mas fica órfão fora do viewport
- Push do WBP_HUD no Stack_Game funcionava mas widget pai (RootLayout)
estava fora do viewport → invisível
- UUIFrontEndFlowSubsystem::EnsureRootLayout (público) recria via
UIManagerSubsystem (idempotente)
- UUIInGameFlowSubsystem::StartInGame chama EnsureRootLayout antes do push
## PlayerCharacter simplificado
- Removido AttributeComponent (vai pro PlayerState via Registry)
- Removido HudHpSpWidgetClass + spawn manual de HUD
- HandleLocalSpawnReady só faz seed do EntityId via PlayerState
- UI lifecycle agora é responsabilidade do AZMMOHUD::BeginPlay
## Verificação (smoke test)
PIE: Login -> CharSelect -> Lobby -> EnterWorld
↓
LogZMMO: AZMMOPlayerState ctor: 1 componente(s) no registry
LogZMMO: ZMMOPlayerState: componente registrado [0] ZMMOAttributeComponent
LogZMMO: FrontEndFlow::EnsureRootLayout: RootLayout recriado
LogZMMO: InGameFlow: state None -> Playing
LogZMMO: InGameFlow: tela Playing pushed em UI.Layer.Game (widget=WBP_HUD_C_0)
LogZMMO: ZMMOHudWidget activated (HpSpBar=WBP_HUD_HpSpBar_C_0)
↓
HUD aparece com Lv 5 / HP 10/200 / SP 5/20 (valores do DB)
Regen funciona (HP/SP enchem a cada 6s/8s)
Movimento normal (input flui pro Pawn)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
60 lines
3.2 KiB
INI
60 lines
3.2 KiB
INI
[/Script/EngineSettings.GeneralProjectSettings]
|
|
ProjectID=FC3E256F43B2AFD43009F4949B0814BE
|
|
ProjectName=Third Person Game Template
|
|
|
|
; -----------------------------------------------------------------------------
|
|
; ZMMO Theme subsystem (see Source/ZMMO/Game/UI/ZMMOThemeSubsystem.h and
|
|
; ARQUITETURA.md §1.10 / §4.7).
|
|
;
|
|
; - DefaultThemeAsset is the fallback theme (must define every EZMMOThemeKey).
|
|
; - ThemeRegistry maps ThemeId -> seasonal DA_Theme_* asset.
|
|
; - CalendarTable points to DT_ThemeCalendar (FThemeCalendarRow rows).
|
|
; - UIStyleTable points to DT_UI_Styles (FUIStyleRow rows): tokens de estilo
|
|
; (cores/fontes/dimensões) keyed por ThemeId; linha "Default" é o fallback.
|
|
; - DevThemeOverride forces a theme in non-Shipping builds only. Keep commented
|
|
; in production.
|
|
;
|
|
; Paths use the /Game prefix (cooked Content namespace). Uncomment after the
|
|
; assets are actually created in the editor.
|
|
; -----------------------------------------------------------------------------
|
|
[/Script/ZMMO.ZMMOThemeSubsystem]
|
|
;DefaultThemeAsset=/Game/ZMMO/UI/Themes/DA_Theme_Default.DA_Theme_Default
|
|
;+ThemeRegistry=(("Christmas", "/Game/ZMMO/UI/Themes/DA_Theme_Christmas.DA_Theme_Christmas"))
|
|
;+ThemeRegistry=(("Halloween", "/Game/ZMMO/UI/Themes/DA_Theme_Halloween.DA_Theme_Halloween"))
|
|
;CalendarTable=/Game/ZMMO/UI/Themes/DT_ThemeCalendar.DT_ThemeCalendar
|
|
UIStyleTable=/Game/ZMMO/Data/UI/DT_UI_Styles.DT_UI_Styles
|
|
;DevThemeOverride=Christmas
|
|
|
|
[/Script/ZMMO.UIFrontEndFlowSubsystem]
|
|
; Mapa estado->tela. O DA já existe (RootLayoutClass = WBP_PrimaryGameLayout);
|
|
; StateScreens fica vazio até os WBPs de página virem do Zeus UMG Forge (§4.8).
|
|
ScreenSetAsset=/Game/ZMMO/UI/FrontEnd/DA_FrontEndScreenSet.DA_FrontEndScreenSet
|
|
|
|
; Fase 4 — char spawn DB-driven. DT_Maps espelha o `maps_config.json` do
|
|
; server (Server/ZeusServerEngine/Config/DataTables/maps_config.json) — o
|
|
; cliente resolve `mapId -> ClientLevel/spawns` via FZMMOMapDef rows.
|
|
MapsTableAsset=/Game/ZMMO/Data/World/DT_Maps.DT_Maps
|
|
|
|
; -----------------------------------------------------------------------------
|
|
; UI in-game (PR 19+). Espelho do front-end pattern:
|
|
; - ScreenSetAsset mapeia EZMMOInGameUIState -> WBP (Playing -> WBP_HUD,
|
|
; StatusWindow -> WBP_StatusWindow, etc.)
|
|
; - Subsystem orquestra: AZMMOHUD::BeginPlay chama StartInGame que vai pra
|
|
; Playing.
|
|
; Asset criado via MCP em /Game/ZMMO/UI/InGame/DA_InGameScreenSet.
|
|
; -----------------------------------------------------------------------------
|
|
[/Script/ZMMO.UIInGameFlowSubsystem]
|
|
ScreenSetAsset=/Game/ZMMO/UI/InGame/DA_InGameScreenSet.DA_InGameScreenSet
|
|
|
|
; -----------------------------------------------------------------------------
|
|
; PlayerState Component Registry (PR 19+). Cada módulo MMO registra seus
|
|
; UActorComponent aqui. O AZMMOPlayerState lê esta lista no construtor e
|
|
; instancia cada classe como subobject — pattern Open-Closed: adicionar
|
|
; Inventory/Skills/Guild = mais uma linha aqui, sem editar AZMMOPlayerState.
|
|
;
|
|
; Convenção: usa o path /Script/<Module>.<ClassName> (sem o "U" do prefixo
|
|
; C++; UClass resolve pelo nome curto).
|
|
; -----------------------------------------------------------------------------
|
|
[/Script/ZMMO.ZMMOPlayerState]
|
|
+ComponentClasses=/Script/ZMMOAttributes.ZMMOAttributeComponent
|