(Feat) Add MainMenu

This commit is contained in:
2026-07-28 14:10:17 +02:00
parent ed7c7fd991
commit 175bef228c
33 changed files with 2331 additions and 12 deletions
+38 -4
View File
@@ -44,8 +44,9 @@ qu'un assemblage de composants plus la caméra et le déplacement.
| Nature | Emplacement |
|---|---|
| Le corps : déplacement, caméra, inventaire, stats, interaction | **Pawn** |
| Le joueur : widgets HUD, input d'interface (Tab, Q, hotbar) | **PlayerController** |
| Le joueur : widgets HUD, input d'interface (Tab, Q, hotbar, Échap) | **PlayerController** |
| Les règles de la partie, le respawn | **GameMode** |
| Ce qui survit au changement de map : réglages, sauvegarde | **GameInstance** |
| Ce que les autres savent de toi (plus tard, si multi) | **PlayerState** |
**Données vs état.** `UItemDataAsset` décrit ce qu'un objet **est** (nom, mesh, icône, effets).
@@ -64,6 +65,15 @@ pour itérer en PIE sans recompiler.
`TWeakObjectPtr` ne permet pas de détecter une transition par simple comparaison de pointeurs,
il faut un booléen d'état à côté.
**Le mode d'input vit sur le viewport, pas sur le controller.** `OpenLevel` détruit le
PlayerController mais pas la fenêtre : un controller qui arrive sur une map ne doit jamais
supposer l'état laissé par la précédente, il repose son `SetInputMode`. Symptôme quand on
l'oublie, en Standalone seulement : la caméra ne répond qu'au clic droit maintenu.
**Enhanced Input en pause** : un jeu en pause ne fait qu'un tick d'input réduit, où seules les
actions cochées **« Trigger When Paused »** sont évaluées. C'est une case sur l'asset `IA_`,
pas du C++ — et son corollaire est qu'aucune action du pawn ne se déclenche en pause.
## Systèmes en place
| Système | Fichiers |
@@ -74,6 +84,10 @@ il faut un booléen d'état à côté.
| Objets | `ItemDataAsset`, `PickupItem` |
| Inventaire | `InventoryComponent`, `InventoryWidget`, `InventorySlotWidget`, `HotbarWidget`, `InventoryDragDropOperation` |
| Survie | `SurvivalStatsComponent`, `SurvivalStatsWidget` |
| Menu principal | `MainMenuGameMode`, `MainMenuPlayerController`, `MainMenuWidget`, `MenuCameraSpot` |
| Menu de pause | `PauseMenuWidget` + la partie pause de `FpsPlayerController` |
| Réglages | `SurvivalUserSettings`, `SettingsMenuWidget`, `SettingsTabWidget`, `SettingsGameplayWidget`, `SettingRowWidget` |
| Fondus, boîtes de dialogue | `ScreenFadeComponent`, `ConfirmDialogWidget` |
### Décisions de gameplay figées
@@ -93,7 +107,18 @@ il faut un booléen d'état à côté.
- **Fondus** : un unique voile plein écran `WBP_Fade` au ZOrder 1000. Fondre widget par widget
est fragile — les cases réécrivent leur propre `RenderOpacity`.
- Après un respawn, le pawn est un **nouvel acteur** : les widgets doivent se rebrancher via
`BindToOwningPawn()`, appelé depuis `OnPossess`.
`BindToOwningPawn()`, appelé depuis `OnPossess`. Même raison côté réglages : le pawn les
**relit** à son `BeginPlay` et s'abonne à `OnSurvivalSettingsApplied`.
- **Échap** a une priorité explicite dans `HandlePauseInput()` : boîte de confirmation →
réglages → inventaire → pause. Sans cet ordre, deux écrans se retrouvent ouverts en même temps.
- **Menu de pause** : `SetPause(true)` fige le monde, mais **pas Slate** — les animations UMG et
`ScreenFadeComponent` continuent (d'où son `bTickEvenWhenPaused`). Pas de bouton « Quitter le
jeu » : la sortie se fait depuis le menu principal.
- **Réglages** : `USurvivalUserSettings` fait autorité, jamais le CDO du pawn. Application
immédiate, aucun bouton « Appliquer » ; la sauvegarde a lieu à la fermeture de l'écran.
L'écran ignore qui l'ouvre (`OnCloseRequested`), d'où un seul `WBP_Settings` pour le menu
principal et la pause. Une ligne = un index dans une liste de paliers, y compris les nombres :
d'où un seul `WBP_SettingRow` pour tout le menu.
## Conventions
@@ -108,9 +133,18 @@ il faut un booléen d'état à côté.
## État actuel et suite
Boucle complète : récolter → ranger → consommer → survivre → mourir → réapparaître.
Autour : menu principal, menu de pause, et un écran de réglages dont **seul l'onglet
« Jeu & Contrôles » est rempli**.
Prochaine étape recommandée : **spawner de ressources avec repousse** (`AResourceSpawner`,
liste pondérée de DataAssets, rayon, densité, délai). Sans lui la carte se vide en dix minutes.
Suite immédiate sur les réglages, dans l'ordre : onglet **Affichage** (le moteur fait tout,
prévoir la confirmation à rebours de 10 s sur la résolution), onglet **Graphismes** (les dix
curseurs de `UGameUserSettings` ; végétation et distance d'affichage comptent double avec
SoStylized), onglet **Audio** quand des `SoundClass` existeront, et enfin le **remappage des
touches** via `UEnhancedInputUserSettings` — le seul morceau réellement coûteux.
Prochaine étape gameplay recommandée : **spawner de ressources avec repousse**
(`AResourceSpawner`, liste pondérée de DataAssets, rayon, densité, délai). Sans lui la carte se
vide en dix minutes.
Ensuite, par ordre de valeur : craft, objet visible en main, coffres, sauvegarde,
cycle jour/nuit.