ed7c7fd991
Boucle de jeu complète : récolte, inventaire, consommation, stats de survie, mort et respawn. Gameplay en C++, Blueprints réservés au câblage d'assets. Assets binaires (.uasset, .umap, textures, audio) suivis via Git LFS. Binaries/, Intermediate/, Saved/ et DerivedDataCache/ sont ignorés : régénérés au build, ils pèsent 3 Go pour 1,3 Go de contenu utile. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
117 lines
6.3 KiB
Markdown
117 lines
6.3 KiB
Markdown
# Survival_projet — Unreal Engine 5.8
|
|
|
|
Jeu de survie solo à la première personne, gameplay écrit en **C++**, Blueprints réservés au
|
|
câblage d'assets. Inspirations assumées : Raft, Aloft, Valheim, esthétique solarpunk.
|
|
Assets d'environnement : pack **SoStylized** (sa végétation n'est pas à l'échelle humaine).
|
|
|
|
## Interlocuteur
|
|
|
|
L'auteur vient de **Unity** et découvre Unreal. Il écrit en français — **répondre en français**.
|
|
|
|
Faire systématiquement le parallèle Unity quand un concept nouveau apparaît
|
|
(Blueprint ≈ prefab, DataAsset ≈ ScriptableObject, ActorComponent ≈ MonoBehaviour,
|
|
BeginPlay ≈ Start, Trace Channel ≈ LayerMask). Il raisonne déjà très bien en composants,
|
|
inutile de réexpliquer les bases.
|
|
|
|
Signaler en revanche les endroits où le modèle **diverge réellement** de Unity, ce sont ceux
|
|
qui le piègent : framework GameMode/Controller/Pawn imposé, `UPROPERTY` obligatoire pour le GC,
|
|
constructeur qui tourne dans l'éditeur (CDO), pas de matrice de collision globale.
|
|
|
|
Il valide les décisions de design lui-même. Proposer **une recommandation argumentée**, pas un
|
|
catalogue d'options. Quand un choix change matériellement le code (modèle d'inventaire, règles
|
|
de mort), demander avant de coder plutôt que de deviner.
|
|
|
|
## Compiler
|
|
|
|
```powershell
|
|
& "C:\Program Files\Epic Games\UE_5.8\Engine\Build\BatchFiles\Build.bat" Survival_projetEditor Win64 Development -Project="d:\Projet\Perso\Unreal\Survival_projet\Survival_projet.uproject" -WaitMutex
|
|
```
|
|
|
|
- Un DLL nommé `UnrealEditor-Survival_projet-000N.dll` signifie que **l'éditeur était ouvert** :
|
|
c'est un hot reload. Prévenir l'auteur de fermer et relancer l'éditeur.
|
|
- `-Rebuild` échoue tant que l'éditeur tourne (DLL verrouillés).
|
|
- **Ne jamais réécrire en masse les timestamps** des fichiers source pour forcer un build.
|
|
- L'outil Edit renvoie parfois `EPERM` sur `FpsPlayer.cpp` (watcher qui tient le handle) :
|
|
réessayer, ou passer par Write sur le fichier entier.
|
|
|
|
## Règles d'architecture établies
|
|
|
|
**Un système = un `UActorComponent`.** Jamais de logique empilée dans `AFpsPlayer`, qui n'est
|
|
qu'un assemblage de composants plus la caméra et le déplacement.
|
|
|
|
**Où va quoi** — le critère est « si le pawn meurt, est-ce que ça doit survivre ? » :
|
|
|
|
| Nature | Emplacement |
|
|
|---|---|
|
|
| Le corps : déplacement, caméra, inventaire, stats, interaction | **Pawn** |
|
|
| Le joueur : widgets HUD, input d'interface (Tab, Q, hotbar) | **PlayerController** |
|
|
| Les règles de la partie, le respawn | **GameMode** |
|
|
| 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).
|
|
Quantité, charges restantes, durabilité sont de l'**état** et vivent sur le slot ou l'acteur.
|
|
Mettre de l'état dans un DataAsset le partagerait entre toutes les instances du jeu.
|
|
|
|
**Un Blueprint par comportement, un DataAsset par objet.** 200 objets et 3 comportements
|
|
donnent 3 Blueprints et 200 DataAssets. `BP_Pickup` est générique, son `ItemData` change
|
|
par instance.
|
|
|
|
**Réglages exposés.** Toute valeur qui se règle à l'œil est une `UPROPERTY(EditAnywhere)`,
|
|
pour itérer en PIE sans recompiler.
|
|
|
|
**Pièges C++ Unreal rencontrés** : ne pas nommer un membre `Player`, `OldPawn`, `Slot` ou
|
|
`CrouchedEyeHeight` dans une classe dérivée du moteur (masquage → erreur C4458 / UHT).
|
|
`TWeakObjectPtr` ne permet pas de détecter une transition par simple comparaison de pointeurs,
|
|
il faut un booléen d'état à côté.
|
|
|
|
## Systèmes en place
|
|
|
|
| Système | Fichiers |
|
|
|---|---|
|
|
| Personnage, caméra, game feel | `FpsPlayer.h/.cpp` |
|
|
| HUD, input d'interface, fondus, respawn | `FpsPlayerController.h/.cpp` |
|
|
| Interaction (trace + interface) | `Interactable.h`, `InteractionComponent`, `InteractionPromptWidget` |
|
|
| Objets | `ItemDataAsset`, `PickupItem` |
|
|
| Inventaire | `InventoryComponent`, `InventoryWidget`, `InventorySlotWidget`, `HotbarWidget`, `InventoryDragDropOperation` |
|
|
| Survie | `SurvivalStatsComponent`, `SurvivalStatsWidget` |
|
|
|
|
### Décisions de gameplay figées
|
|
|
|
- **Inventaire** : un seul `TArray` de 30 slots. Index **0-9 = barre rapide**, **10-29 = grille**.
|
|
Conteneurs **indépendants** (un objet dans la barre n'apparaît pas dans la grille), même
|
|
tableau uniquement pour que le glisser-déposer n'ait aucune conversion d'index à faire.
|
|
- **Ramassage** : complète les piles existantes partout, puis ouvre un slot dans la **barre en
|
|
priorité**, puis déborde dans la grille.
|
|
- **Glisser** : normal = pile entière, **Maj** = moitié arrondie au supérieur, **Ctrl** = un seul.
|
|
Lâcher hors de la grille jette au sol ; lâcher entre deux cases est absorbé (jamais de perte
|
|
accidentelle).
|
|
- **Clic gauche** = utiliser l'objet actif de la barre. Bindé sur le **pawn**, donc muet quand
|
|
l'inventaire est ouvert — le conflit avec le drag & drop se règle tout seul.
|
|
- **Objets à charges** (`MaxUses > 1`) ne s'empilent jamais. Les valeurs de restauration
|
|
s'appliquent **par utilisation**. L'usure suit l'objet jusqu'au sol et revient avec lui.
|
|
- **Mort** : tout tombe au sol autour du corps, respawn au `PlayerStart`, jauges pleines.
|
|
- **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`.
|
|
|
|
## Conventions
|
|
|
|
- Commentaires **en français**. Ils expliquent le *pourquoi* et les pièges, jamais le *quoi*.
|
|
- Nommage éditeur : `BP_` acteurs, `WBP_` widgets, `DA_` data assets, `IA_` input actions,
|
|
`IMC_` mapping contexts, `GM_` game mode.
|
|
- Widgets : classe C++ `Abstract` pour la logique, Widget Blueprint enfant pour la mise en page.
|
|
Les widgets liés utilisent `meta = (BindWidget)`, ou `BindWidgetOptional` quand l'élément
|
|
est décoratif.
|
|
- Les widgets s'abonnent à des délégués, **jamais de Tick** pour lire un état.
|
|
|
|
## État actuel et suite
|
|
|
|
Boucle complète : récolter → ranger → consommer → survivre → mourir → réapparaître.
|
|
|
|
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.
|
|
|
|
Ensuite, par ordre de valeur : craft, objet visible en main, coffres, sauvegarde,
|
|
cycle jour/nuit.
|