(Feat) Add Animation

This commit is contained in:
2026-08-06 13:27:21 +02:00
parent fca1b271f1
commit 72a34f6e40
64 changed files with 1943 additions and 83 deletions
+48 -2
View File
@@ -115,6 +115,7 @@ qu'une compilation propre l'est vraiment.
| Système | Fichiers |
|---|---|
| Personnage, caméra, game feel | `FpsPlayer.h/.cpp` |
| Balancement de tête procédural | `HeadBobComponent` (profils par état, additionné dans `ApplyCameraTransform`) |
| HUD, input d'interface, fondus, respawn | `FpsPlayerController.h/.cpp` |
| Interaction (trace + interface) | `Interactable.h`, `InteractionComponent`, `InteractionPromptWidget` |
| Objets | `ItemDataAsset`, `PickupItem` |
@@ -127,6 +128,8 @@ qu'une compilation propre l'est vraiment.
| Écran à onglets (inventaire / craft) | `InventoryScreenWidget` |
| Menu de pause | `PauseMenuWidget` + la partie pause de `FpsPlayerController` |
| Réglages | `SurvivalUserSettings`, `SettingsMenuWidget`, `SettingsTabWidget`, `SettingsGameplayWidget`, `SettingRowWidget` |
| Musique | `MusicDirector`, `MusicSubsystem`, `MusicPlaylistDataAsset` |
| Audio (volumes) | `SurvivalAudioSettings`, `SettingsAudioWidget` + `USurvivalUserSettings::ApplyAudioSettings` |
| Fondus, boîtes de dialogue | `ScreenFadeComponent`, `ConfirmDialogWidget` |
| Coop Steam (sessions) | `SessionSubsystem`, `SurvivalGameMode`, `SurvivalGameState`, `SurvivalPlayerState` |
| Pseudo au-dessus des joueurs | `PlayerNameplateComponent`, `PlayerNameplateWidget` |
@@ -384,6 +387,49 @@ jetée**. On route donc toujours par l'inventaire du pawn local, et la source co
sont passées en paramètres — jamais déduites du récepteur, sinon « Tout prendre » viderait le sac
du joueur dans lui-même.
### Audio — le mixage passe par les SoundClass, et par rien d'autre
- **Une hiérarchie de `SoundClass`, un `SoundMix`, quatre curseurs.** `SC_Master` est la
racine ; `SC_Music`, `SC_SFX` et `SC_UI` en descendent. Le moteur multiplie déjà le volume
du parent dans celui de l'enfant, donc le volume général est gratuit — pas de produit à
calculer en C++.
- **`SM_Settings` est déclaré comme *Default Base Sound Mix*** dans Project Settings > Audio,
et le C++ le relit à cet endroit au lieu d'en garder une référence à lui. Deux raisons : un
mix de base est **rejoué à plein régime en permanence** (un mix poussé à la main s'éteindrait
au bout de sa durée), et le moteur le **repose à chaque chargement de map** — donc les
volumes traversent les transitions sans une ligne de code. Une seconde référence côté projet
n'apporterait qu'un risque de divergence.
- **`bApplyToChildren = true` sur le maître, `false` sur les trois autres.** C'est le piège de
ce système : le moteur propage les propriétés parent → enfant (`ParseSoundClasses`) **avant**
d'appliquer les ajusteurs du mix (`ApplyClassAdjusters`). Un ajusteur posé sur `SC_Master`
arrive donc trop tard pour redescendre tout seul. Sans ce drapeau, le volume général n'agit
que sur les sons rangés *directement* dans `SC_Master` — c'est-à-dire quasiment rien, et le
symptôme se lit comme « le curseur maître ne fait rien ».
- **Aucun fondu sur `SetSoundMixClassOverride``FadeInTime` vaut 0.** Ce n'est pas une
simplification : toute durée non nulle rend le curseur inutilisable. Reposer un override
avant la fin du précédent relance l'interpolation (`FDynamicParameter::Set` remet
`CurrTimeSec` à zéro) **sans** appeler `Update(DeltaTime)` la même frame. Un curseur qu'on
glisse repose l'override à chaque image, donc la rampe repart indéfiniment de zéro et le
volume ne rattrape son retard qu'une fois le geste **arrêté**. Le mixeur lisse déjà le gain
de chaque source dans son buffer de rendu : à zéro il n'y a pas de clic pour autant.
- **`SC_SFX` est la *Default Sound Class* du projet.** Un son qui n'annonce pas sa classe
atterrit donc dans les effets plutôt que nulle part : oublier de taguer un bruitage le laisse
quand même sous le curseur Effets. Seuls les sons d'interface se taguent à la main.
- **La musique impose sa classe depuis le code** (`SoundClassOverride` posé par
`UMusicSubsystem`), pas depuis les assets : ajouter une piste à une playlist ne doit pas
demander de penser à la taguer. Corollaire, `UMusicSubsystem::SetMusicVolume` **n'est pas** le
réglage du joueur — deux chemins vers le même volume finiraient par se multiplier.
- **Les volumes sont des pourcentages, élevés au carré avant d'être envoyés.** L'oreille répond
au logarithme de l'amplitude : un curseur envoyé tel quel donne un réglage où tout se joue
dans les vingt derniers pourcents. À 50 %, l'amplitude vaut 0,25, soit environ la moitié du
volume *perçu*.
- **`ApplyAudioSettings()` est séparée d'`ApplySurvivalSettings()`** : cinq commandes vers le
thread audio à chaque cran du champ de vision seraient du bruit pur. `ApplyNonResolutionSettings`
appelle les deux, donc le démarrage n'en oublie aucune.
- **Le jeu est muet en arrière-plan par défaut, et c'est le moteur qui le décide**
(`FApp::UnfocusedVolumeMultiplier`, dont la valeur d'usine est 0). Le réglage ne fait que
l'exposer ; il ne passe pas par le mix, puisqu'il baisse l'application entière bien en amont.
### Décisions de gameplay figées
- **Inventaire** : un seul `TArray` de 30 slots. Index **0-9 = barre rapide**, **10-29 = grille**.
@@ -576,8 +622,8 @@ vide en dix minutes. À écrire **serveur-autoritaire d'emblée** — c'est un a
Ensuite, par ordre de valeur : objet visible en main, sauvegarde, cycle jour/nuit.
> **Systèmes présents dans `Source/` mais pas encore décrits ici** : `MusicDirector`,
> `MusicSubsystem`, `MusicPlaylistDataAsset`, `SettingsDisplayWidget`, `SettingsGraphicsWidget`,
> **Systèmes présents dans `Source/` mais pas encore décrits ici** :
> `SettingsDisplayWidget`, `SettingsGraphicsWidget`,
> `SettingsControlsWidget`, `SettingKeyRowWidget`, `KeyCaptureWidget`. Ils sont arrivés en dehors
> des sessions qui ont produit ce document — à documenter quand on y touchera, plutôt que de
> décrire de mémoire un code qu'on n'a pas lu.