Point de restauration avant réorganisation de Content (2026-10-30)

Squelettes des anims AGIS, groupes de slots, bases de nage, WBP_PauseMenu,
couverture et visuels MetaHuman tels qu'avant le rangement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DodoandClaude Opus 5.5 committed 2026-10-30 18:36:43 +01:00
1 parent 8f6e6d5e31
commit e829ff2808
34 files changed
+222 -68

No files matched your search

+136 -8
View File
@@ -26,7 +26,7 @@ Le projet est construit par empilement de **trois grands blocs** de contenu, plu
2. **Système d'inventaire AGIS** ("Advanced Grid Inventory System", asset marketplace) — `Content/Core/Coreinventory/`, `Content/Systems/Inventory/`, `Content/UI/Inventory_UI/`, `Content/Data/Inventory_Data/`.
C'est le **cœur du gameplay** : inventaire en grille, équipement, craft, loot, sauvegarde. La quasi-totalité des systèmes de jeu ajoutés par l'équipe (stats, mort, sélection rapide d'équipement, interactables) se branchent sur ce système.
3. **Systèmes de jeu spécifiques au projet**, ajoutés par-dessus AGIS — `Content/Systems/Stats/`, `Content/Systems/Scent/`, `Content/Systems/Movable_Object/`, `Content/Systems/Door/`, `Content/PCG/`, `Content/Items/`, `Content/UI/Widgets/` (HUD, pause menu). C'est ici que la majorité des évolutions de gameplay futures doivent être ajoutées.
3. **Systèmes de jeu spécifiques au projet**, ajoutés par-dessus AGIS — `Content/Systems/Stats/`, `Content/Systems/Scent/`, `Content/Systems/Movable_Object/`, `Content/Systems/Door/`, `Content/PCG/` (dont le système de routes et ponts `PCG/RoadNetwork/`, §7), `Content/Items/`, `Content/UI/Widgets/` (HUD, pause menu). C'est ici que la majorité des évolutions de gameplay futures doivent être ajoutées.
4. **Outillage IA** — plugins `VibeUE`, `EditorToolset`, `ModelContextProtocol`, `Terminal` (déclarés dans `ProjectFv1.uproject`) + `.mcp.json` à la racine. Ils exposent l'éditeur Unreal (Blueprints, Widgets, Input, PCG, Landscape, Niagara, etc.) à un serveur MCP local (`http://127.0.0.1:8000/mcp`) piloté par des agents Claude. **C'est le mécanisme par lequel un modèle d'IA lit/modifie ce projet** — voir la section [9. Notes pour les IA](#9-notes-pour-les-ia-pièges-connus-de-loutillage) pour les pièges connus.
@@ -137,7 +137,12 @@ Character (Pawn, géré par le framework "Sandbox Character")
│ SamplingRange corrigées, on pourra lui dédier une vraie ligne armée accroupie plutôt que le repli.
│
├─ Composants de mouvement (Content/Systems/Movement/, Systems/Blueprints/MovementModes/)
│ └─ AC_ClimbingComponent, AC_Cover, AC_TraversalLogic, AC_PreCMCTick, AC_VisualOverrideManager…
│ └─ AC_ClimbingComponent, AC_TraversalLogic, AC_PreCMCTick, AC_VisualOverrideManager…
│
├─ Couverture + interactions AST (Content/Systems/Movement/Cover|Interaction|StateManager|ASTShared, §4.2.5)
│ └─ SandboxCharacter_Mover porte BPC_StateManager (hub d'états) + BPC_CoverSystem + BPC_Interaction ;
│ Get_MoveInput / Get_RotationMode / Get_Gait / Get_OrientationIntent / ProduceInput lisent le
│ StateManager ; SandboxCharacter_Mover_ABP lie les calques OverlayGraph (tag Overlay) et InteractionIKGraph.
│
├─ Composant AIPerceptionStimuliSourceComponent (2026-09-05)
│ └─ Ajouté sur SandboxCharacter_CMC pour que le joueur soit détectable par la vue de l'IA
@@ -224,6 +229,8 @@ ProjectF/
│
├── Config/ → Configuration moteur & jeu (voir détail §7)
├── Content/ → Tous les assets du jeu (voir détail §3 à §6)
├── Docs/ → Documentation de systèmes : `PCG_RoutesPonts.md` (système PCG routes et ponts, §7), `PCG_Haussmann.md` (système PCG
│ d'immeubles haussmanniens, §7), avec leurs captures de vérification (`*_captures/`)
│
├── Binaries/, Intermediate/, Saved/, DerivedDataCache/ → Générés par l'éditeur, exclus de Git, jamais à éditer/documenter
```
@@ -402,7 +409,7 @@ Content/Systems/Mover/
├── SandboxCharacter_Mover_ABP.uasset → Anim Blueprint du Mover (utilise `Systems/Aiming/ABP_AimingMaster`). (2026-09-18) Deux corrections majeures : (1) les nœuds `Evaluate Chooser` de `Update_MotionMatching` n'avaient AUCUN objet de contexte branché (au CMC il est relié à `self`) → le chooser ne pouvait résoudre aucune de ses colonnes, `ValidDatabases` restait vide et la branche Motion Matching de l'`AnimGraph` était morte ; `self` est désormais branché sur les deux nœuds. (2) Nouvelle variable `AnimBranchIndex` (affectée en fin d'`Update_Logic`) branchée sur l'`ActiveChildIndex` du *Blend Poses by int* de l'`AnimGraph`. Elle a d'abord piloté un hybride (Motion Matching en prone/nage, state machine GASP sinon) ; **depuis le 2026-09-18 elle vaut la constante `0`** : l'ABP du Mover est **100 % Motion Matching** (chooser `CHT_PoseSearchDatabases_Mover`), la state machine « State Controller » n'est plus jamais évaluée. Le nœud `Set AnimBranchIndex` et la variable sont conservés pour pouvoir rebasculer sur la voie 1 en changeant une seule valeur. Variables `Is Armed` et `IS Moving Object` ajoutées pour les colonnes du chooser copié.
├── GM_Sandbox.uasset / PC_Sandbox.uasset → GameMode (pawn = SandboxCharacter_Mover) et PlayerController du Mover ; création du widget de démo retirée le 2026-09-14
├── AC_TraversalLogic.uasset → Traversal du personnage Mover (vault/mantle/hurdle/climb). (2026-09-15) La détection de rebords du sample (limitée aux blocs de démo `LevelBlock_Traversable`, retirée le 2026-09-14) est remplacée par celle de `Systems/Blueprints/AC_TraversalLogic` (CMC), portée à l'identique : variables `Min Ledge Width`, `Min Front Ledge Depth`, `Max Ledge Sideways Depth`, `Trace Complex`, `Show Trace`, `Persistent Show Trace`, `RespectPlayersFacingDir`, `Banned Tags` (mêmes valeurs par défaut) et fonctions `ComputeLedgeData`, `TraceAlongHitPlane`, `TraceCorners`, `TraceWidth`, `NudgeTraceTowardsObjectOrigin`, `Set Trace Hit Point`, `Tag Compare`. Dans `TryTraversalAction` : capsule trace sur `TraceTypeQuery1` (Visibility, au lieu du canal `Traversable`), `Hit` → tags acteur+composant → `ComputeLedgeData` → rebords avant/arrière écrits dans `TraversalCheckResult` (équivalent inliné de `TryAndCalculateLedges`, non recopiée car elle prend le struct Systems par référence), puis `Tag Compare` (tags bannis) avant le chooser `CHT_TraversalMontages_Mover`. Le déclenchement (`IA_Jump` → `CanDoTraversal` → `TryTraversalAction`) et l'exécution Mover (`PerformTraversalAction_Mover`, mode `Traversing`) sont inchangés. Les deux composants restent des doublons divergents (structs/BPI `Systems/Mover/` vs `Systems/Blueprints/`).
├── AC_PreCMCTick, AC_PostABPTick, AC_VisualOverrideManager → Composants du sample (versions GASP, divergentes de celles de `Systems/Blueprints/`)
├── AC_PreCMCTick, AC_PostABPTick, AC_VisualOverrideManager → Composants du sample (versions GASP, divergentes de celles de `Systems/Blueprints/`). (2026-09-27) `AC_VisualOverrideManager` réattache aussi les hitboxes du pion au MetaHuman (`AttachHitboxesTo`, voir §4.2.4)
├── BPI_SandboxCharacter_Pawn / _ABP.uasset → Interfaces GASP implémentées par la chaîne Mover
├── AI/StateTree/ → `ST_Player_SandboxCharacter_SmartObject` + tâches (copie GASP)
├── AnimModifiers/ → `AM_BakePhaseCurveFromFootstepNotifies`, `AM_FootSteps_Run` (référencés par quelques anims `UEFN_Mannequin`)
@@ -421,11 +428,11 @@ Content/Blueprints/AnimNotifies/ → SEUL reste de `Content/Blueprints
Ces trois fonctionnalités n'existaient que sur `SandboxCharacter_CMC` (via le `CharacterMovementComponent`). Elles ont été reportées sur `Core/Character/SandboxCharacter_Mover`, en passant par les mécanismes du plugin Mover et non par des écritures directes sur la capsule.
- **Composants ajoutés au Mover** : `Systems/Movement/Cover/AC_Cover` (le composant du CMC, générique : il travaille via `GetOwner`) et `Arrow1` (ArrowComponent, `(0,0,90)` / yaw 90). ⚠️ `Arrow1` DOIT être attaché au **SkeletalMesh** (comme au CMC) et non à la capsule : le mesh porte un yaw −90, donc l'arrow attaché au mesh se retrouve aligné sur l'acteur (avant = avant de l'acteur, droite = droite de l'acteur), ce qu'attend le sphere trace de `MoveAlongWall` (il part de 55 uu sur le côté puis trace 60 uu vers l'avant, dans le mur). Attaché à la capsule, ses axes sont tournés de 90° : le trace part dans le vide, `MoveAlongWall` ne produit aucun `AddMovementInput` et on ne peut pas se déplacer en couverture (bug corrigé le 2026-09-18).
- **Composants ajoutés au Mover** : `Systems/Movement/Cover/AC_Cover` *(supprimé depuis, remplacé par la couverture AST — §4.2.5)* (le composant du CMC, générique : il travaille via `GetOwner`) et `Arrow1` (ArrowComponent, `(0,0,90)` / yaw 90). ⚠️ `Arrow1` DOIT être attaché au **SkeletalMesh** (comme au CMC) et non à la capsule : le mesh porte un yaw −90, donc l'arrow attaché au mesh se retrouve aligné sur l'acteur (avant = avant de l'acteur, droite = droite de l'acteur), ce qu'attend le sphere trace de `MoveAlongWall` (il part de 55 uu sur le côté puis trace 60 uu vers l'avant, dans le mur). Attaché à la capsule, ses axes sont tournés de 90° : le trace part dans le vide, `MoveAlongWall` ne produit aucun `AddMovementInput` et on ne peut pas se déplacer en couverture (bug corrigé le 2026-09-18).
- **Variables ajoutées au Mover** — catégorie `Cover` : `In Cover`, `Cover` (`E_CoverD`), `Edge L`, `Edge R` ; catégorie `Prone` : `IsProne`, `ProneHalfHeight` (40), `CrouchHalfHeight` (55) ; catégorie `Swimming` : `CurrentWaterBodyComp`, `IsSwimming`, `IsUnderwater`, `SwimSprint`, `WaterSurfaceZ`, `WaterDepth`, `SwimVerticalInput`, `SwimStartDepth` (95), `SwimStopDepth` (80), `SwimmingModeClass`.
- **Prone** : `IA_Prone` → `ToggleProne` (bascule `IsProne` + `WantsToCrouch`/`WantsToStrafe` dans `PlayerInputState`), refusé en nage ou en cover. La hauteur de capsule N'est PAS écrite directement (contrairement au CMC qui fait `SetCapsuleSize`) : `Apply_CrouchOrProne`, appelée depuis `On_PreSimulateTick`, règle `StanceSettings.CrouchHalfHeight` (40 en prone, 55 accroupi) et force un cycle `UnCrouch`→`Crouch` quand la capsule courante ne correspond pas — c'est le `FStanceModifier` du plugin qui redimensionne la capsule, replace l'acteur et décale le mesh. `IA_Crouch` en prone appelle `ExitProneToCrouch` (retour accroupi).
- **Nage** : les overlaps de la capsule (`OnComponentBegin/EndOverlap` → cast `WaterBody`) renseignent `CurrentWaterBodyComp` ; `Update_Swimming` (appelée depuis `On_PreSimulateTick`, voir l'encadré « tick » plus bas) lit `GetWaterSurfaceInfoAtLocation` (surface + profondeur), met à jour `SwimSprint` (depuis `PlayerInputState.WantsToSprint`) et `SwimVerticalInput` (valeurs brutes de `IA_Jump` − `IA_Crouch`), puis `StartSwimming` (profondeur ≥ `SwimStartDepth` → `QueueNextMovementMode("Swimming")`) / `StopSwimming` (< `SwimStopDepth` → `Falling`). `IA_SwimmingDeep` bascule `IsUnderwater` (plongée). Le mode « Swimming » est enregistré **au BeginPlay** par `AddMovementModeFromClass` (variable `SwimmingModeClass`) et non dans la map `MovementModes` du composant : une instance créée par script dans le template du parent est privée et empêchait la sauvegarde de `SandboxCharacter_Mover_Ragdoll` (« Illegal reference to private object »).
- **Cover** : l'événement `OnEntreredCover` d'`AC_Cover` recopie `InCover`/`cover`/`EdgeL`/`EdgeR` sur le personnage puis `ApplyCoverCrouch` (accroupi **et `WantsToStrafe` = en couverture** tant qu'on y est) ; `IA_Move` appelle `AC_Cover.MoveAlongWall` quand `In Cover`. Comme le Mover ignore `AddMovementInput`, `Get_MoveInput` renvoie, en cover, `ConsumeMovementInputVector` (le vecteur accumulé par le composant). `Update_Cover` (`On_PreSimulateTick`) met `CharacterMover.bAcceptExternalMovement` à la valeur d'`AC_Cover.InCover`, sinon le `MoveComponentTo` de collage au mur serait annulé par la simulation Mover. ⚠️ Le mode **strafe est indispensable** en couverture : sans lui le Mover réoriente le personnage dans la direction du glissement dès le premier pas, l'`Arrow1` tourne avec, le trace de `MoveAlongWall` rate le mur et le déplacement se bloque après quelques centimètres (bug corrigé le 2026-09-18). L'entrée en couverture reste sur la touche **P** : depuis le 2026-09-18 le corps de cet `InputKey` est déporté dans l'événement `ToggleCover` d'`AC_Cover` (la touche P l'appelle), ce qui permet de déclencher la couverture par script/test ou de la remapper plus tard sur une Input Action.
- **Cover** *(⚠️ OBSOLÈTE depuis le 2026-09-27 : `AC_Cover` a été supprimé et remplacé par le système de couverture AST, voir §4.2.5 ; les variables `In Cover`/`Cover`/`Edge L/R`, `ApplyCoverCrouch` et `Update_Cover` restent dans le BP mais ne sont plus alimentées)* : l'événement `OnEntreredCover` d'`AC_Cover` recopie `InCover`/`cover`/`EdgeL`/`EdgeR` sur le personnage puis `ApplyCoverCrouch` (accroupi **et `WantsToStrafe` = en couverture** tant qu'on y est) ; `IA_Move` appelle `AC_Cover.MoveAlongWall` quand `In Cover`. Comme le Mover ignore `AddMovementInput`, `Get_MoveInput` renvoie, en cover, `ConsumeMovementInputVector` (le vecteur accumulé par le composant). `Update_Cover` (`On_PreSimulateTick`) met `CharacterMover.bAcceptExternalMovement` à la valeur d'`AC_Cover.InCover`, sinon le `MoveComponentTo` de collage au mur serait annulé par la simulation Mover. ⚠️ Le mode **strafe est indispensable** en couverture : sans lui le Mover réoriente le personnage dans la direction du glissement dès le premier pas, l'`Arrow1` tourne avec, le trace de `MoveAlongWall` rate le mur et le déplacement se bloque après quelques centimètres (bug corrigé le 2026-09-18). L'entrée en couverture reste sur la touche **P** : depuis le 2026-09-18 le corps de cet `InputKey` est déporté dans l'événement `ToggleCover` d'`AC_Cover` (la touche P l'appelle), ce qui permet de déclencher la couverture par script/test ou de la remapper plus tard sur une Input Action.
- **Alimentation de l'animation** : `Get_PropertiesForAnimation` renvoie désormais `Stance` = Swinning / SwinningDeep / Prone / Crouch / Stand, et `Get_Gait` renvoie Prone en prone, Swinning/SwinningSprint en nage. `Get_MoveInput` utilise la rotation caméra complète (input 3D) en plongée comme en vol. Le chooser `Characters/UEFN_Mannequin/Animations/MotionMatchingData/CHT_PoseSearchDatabases_Mover` est une copie du `_Dense` du CMC dont le `ContextData` pointe sur `SandboxCharacter_Mover_ABP` ; ses deux colonnes booléennes (`Is Armed`, `IS Moving Object`) sont désactivées et la ligne « push » restreinte à `Stance = Stand`.
- **Les deux moteurs d'animation de l'ABP (Motion Matching vs state machine)** : l'`AnimGraph` (CMC comme Mover) contient un `Blend Poses by int` dont l'entrée **0 est le nœud Motion Matching** et l'entrée **1 la state machine « State Controller » + Blend Stack** (la voie « expérimentale » du sample GASP). Voie 0 : `Update_MotionMatching` (fonction de nœud) évalue un chooser qui renvoie une LISTE de `PoseSearchDatabase`, `SetDatabasesToSearch` les donne au nœud, qui recherche chaque frame la meilleure pose d'après la trajectoire (`Update_Trajectory`) — variables `ValidDatabases`, `CurrentSelectedDatabase/Anim`, `MM Search Cost`, réglages `Get_MMBlendTime`/`Get_MMInterruptMode`. Voie 1 : à chaque entrée d'état, `SetBlendStackAnimFromChooser` évalue `CHT_MoverCharacterAnimations_PoseMatch` (chooser **par clip**, une ligne = une animation) qui renvoie UNE anim + ses réglages de blend, poussée dans le `Blend Stack` — variables `StateName`, `BlendStackInputs`, `Search Cost`, `NoValidAnim`. Dans les deux ABP l'index valait la constante `0` (Motion Matching en permanence) ; sur le Mover il passe par la variable `AnimBranchIndex`, qui vaut elle aussi `0` en permanence depuis le 2026-09-18 (l'hybride state machine / Motion Matching a été abandonné à la demande de l'utilisateur, voir §4.2.1). Les CVars GASP `DDCvar.UseExperimentalStateMachine` / `DDCvar.ExperimentalStateMachine` n'existent pas dans ce projet (avertissement « Failed to find console variable » en PIE) : elles ne commandent rien.
- **Correction de `MovementModeMap`** : « Ragdoll » pointait sur *Climbing* et « Flying » sur *SwimmingOnSurface* (décalage laissé par la fusion des enums GASP → projet, §8.2). Remis sur `Ragdoll`/`Flying` + ajout de `Swimming` → `SwimmingOnSurface`. Effet de bord bénéfique : le ragdoll du pion refonctionne (son Tick et `EnteredRagdollSuccessfullyCheck` comparent le mode courant à `Ragdoll`).
@@ -453,7 +460,7 @@ Vérifié en PIE, dans cet ordre : ramassage du fusil → dos ; V+B → main + `
Restant à faire :
- Aucune base Motion Matching armée pour le fusil / le pistolet (seul l'arc en a) ; `PSD_Crouch_Bow` existe mais n'est référencée par aucune ligne de chooser.
- `SandboxCharacter_Mover` n'a **pas** de composant `AC_Stats` (le CMC en a un) : `BFL_WeaponDamage::ApplyPointDamage` résout `AC_Stats` sur la cible, donc le pion Mover ne peut pas encaisser de dégâts. Il lui manque aussi les capsules de hitbox et le `PerceptionStimuliSource` du CMC.
- `SandboxCharacter_Mover` a désormais un `AC_Stats` et ses capsules de hitbox (voir « Hitboxes calées sur le MetaHuman » en §4.2.4) ; il lui manque encore le `PerceptionStimuliSource` du CMC.
- La visée n'a pas d'équivalent de `SandboxCharacter_CMC::ISaiming` sur le Mover (seuls `PlayerInputState.WantsToAim` et `WantToshot` existent).
#### 4.2.4 MetaHuman en « visual override » du personnage Mover (2026-09-19)
@@ -480,12 +487,30 @@ Vérifié en PIE : le mannequin passe invisible, `BP_VisualOverride_MetaHuman` e
⚠️ **Limite structurelle de cette approche** : les objets équipés s'accrochent aux sockets du **mesh pilote caché**, pas du MetaHuman (`Inventory_Equipper` attache sur `OwnerMesh`, qui est le composant `SkeletalMesh` du pion). Mesuré en PIE : ~**12 cm** d'écart entre `hand_r` du mannequin et `hand_r` du MetaHuman — une arme en main flottera d'autant. Correctif à prévoir : pointer `OwnerMesh` sur le composant `Body` de l'override quand un override est actif, ou n'utiliser l'override que pour des skins aux proportions du mannequin.
**Hitboxes calées sur le MetaHuman (2026-09-27)** : les 10 `CapsuleComponent` de hitbox du pion (`Head_Capsule`, `Torso_Capsule`, `harm_Up/Down_L/R_Capsule`, `Leg_Up/Down_L/R_Capsule`) portent le Component Tag **`Hitbox`** et sont dimensionnées d'après le Physics Asset du MetaHuman (`/Game/test/Body/PHYS_test`, rayon +1 cm pour les vêtements, avant-bras prolongé jusqu'au milieu de la main, torse = une capsule de `pelvis` à `spine_04` exprimée dans `spine_01`) ; échelle remise à 1 (l'ancienne échelle non uniforme compensait les os mis à l'échelle du mannequin UEFN : tête ×1,15, jambes ×1,12). `AC_VisualOverrideManager` (`Systems/Mover/`) a une fonction **`AttachHitboxesTo(Target)`** : elle réattache tout composant tagué `Hitbox` du propriétaire sur `Target`, même socket, `KeepRelative`. `ApplyVisualOverride` l'appelle deux fois : d'abord vers le mesh pilote **avant** `SetChildActorClass` (détruire l'override détache les composants étrangers qui y sont attachés, qui perdent alors leur socket), puis vers `GetChildComponent(VisualOverride, 0)` (= `Body`) si un override est actif. Les capsules restent des composants du pion, donc les hits résolvent toujours le pion et son `AC_Stats`. Avec `DDCvar.VisualOverride -1`, elles retombent sur le mannequin, avec des dimensions de MetaHuman (légèrement trop grandes). `Torso_Capsule` et les jambes sont en `NoCollision` (réglage antérieur, inchangé).
Autres points :
- **Portrait de l'inventaire (2026-09-21)** : `RefreshInventoryCapture` (Mover) appelle en fin de chaîne le nouveau custom event `AddAttachedActorsToInventoryCapture`, qui ajoute à la show-only list de `SceneCaptureComponent2D` les composants de chaque acteur attaché au pion (récursif). Sans ça, les objets équipés (vêtements `BP_Item_SurvivorOutfit_*`, armes) n'apparaissaient pas dans le portrait : ils appartiennent à l'acteur item, pas au pion ni à ses child actors.
- Le ragdoll n'a pas été testé avec l'override actif (il simule sur le mesh caché ; le MetaHuman devrait suivre par retarget).
- Les 13 sockets recopiées sur `SKM_test_BodyMesh` lors de la tentative précédente ont été retirées : elles ne servent plus, les attaches restant sur le mannequin.
- Pour ajouter une autre peau : créer `IK_X` + `RTG_UEFN_to_X`, ajouter l'entrée dans `ABP_GenericRetarget.IKRetargeter_Map`, dupliquer `BP_VisualOverride_MetaHuman` en changeant meshes et Component Tag, et l'ajouter à `VisualOverrides_Soft`.
#### 4.2.5 Couverture + interactions portées depuis le projet AST (2026-09-27)
Source : projet frère `E:\AST_V1_17\AST_V1_17` (framework GASP + plugins `AST_*`). Le contenu des plugins Cover / Interaction / StateManager a été copié à la main dans `Systems/Movement/` ; ses références internes (`/AST_CoverSystem/…`, `/AST_StateManager/…`, `/Game/Blueprints/…` du GASP d'AST) sont résolues par les **`[CoreRedirects]` de `Config/DefaultEngine.ini`** (bloc « Port AST ») puis les assets ont été resauvegardés. Ne pas retirer ces redirections tant que tout le contenu AST n'a pas été resauvegardé (ceux hors du périmètre porté, ex. `StateManager/Maps`, gardent les anciens chemins).
- **Personnage `Core/Character/SandboxCharacter_Mover`** : composants `BPC_StateManager` (tag `StateManager`), `BPC_CoverSystem` (tag `CoverSystem`), `BPC_Interaction` (tag `InteractionSystem`) — les tags sont obligatoires, `StateActorComponent::SetComponents` retrouve les composants par tag.
- `IA_TakeCover` (**touche A**, `IMC_Sandbox` — AZERTY, Q = déplacement) `Started` → `BPC_CoverSystem.FindCoverWall`.
- `IA_Interact` (**touche E**, partagée avec les SmartObjects GASP) `Started` → `BPC_Interaction.CheckInteraction(StateManager.GetClosestActor)`.
- `Get_MoveInput` : si `CoverState ≠ None` → pousse l'input brut dans `StateManager.SetMovementInputAsVector` puis renvoie `BPC_CoverSystem.GetCoverMovement` (0 pendant les transitions, `CanCoverMove` faux).
- `Get_RotationMode` (→ Strafe), `Get_Gait` (→ `StateManager.Get_Gait`, qui met aussi à jour la collision de l'objet poussé) et `Get_OrientationIntent` (→ avant de l'acteur) sont court-circuités quand `CoverState ≠ None` **ou** `OverlayState = Pullpush`.
- `ProduceInput` : synchronise `StateManager.SetInputCrouch(PlayerInputState.WantsToCrouch)` et `WantsToCrouch = joueur OR StateManager.Get_Crouch` (couverture basse ⇒ accroupi).
- **ABP `Systems/Mover/SandboxCharacter_Mover_ABP`** : `Slot DefaultSlot → OverlayGraph (Linked Anim Graph, tag Overlay) → Dead Blending` et `Procedural_FullBody → InteractionIKGraph → Pose History`. `Get/Set_InteractionTransform` existaient déjà (GASP 5.8).
- **`OverlayGraph::CanDynamicTransition` renvoie toujours false** : les transitions ALS (petits pas « Grounded Slot ») étaient jouées en montage dynamique et, le slot `Grounded Slot` étant dans `DefaultGroup` du squelette `SK_UEFN_Mannequin` chez nous (groupe à part `GroundedGroup` chez AST), elles interrompaient au bout de 4 frames les montages de couverture/interaction/traversée. Pour les réactiver proprement : dans le squelette → Anim Slot Manager, créer `GroundedGroup` et y déplacer `Grounded Slot` (AST range aussi `HitReactionSlot` dans `HitGroup` et Fire/Legs/Arm R/Curves/Spine/Head/Arm L/Pelvis dans `Layer`) — non scriptable (SlotGroups non exposé à Python).
- `BPC_Interaction::Release PullPush Object` remet l'overlay sur **None** (AST : Default) pour retrouver l'état de départ du perso.
- Vérifié en PIE (`Test/L_ASTCoverTest`) : couverture basse et haute (entrée par montage motion-matché, glissement, demi-tour, sortie en reculant), porte, porte électronique, placard, levier, pousser/tirer. `MapDev1` : aucune erreur runtime liée à AST.
- **Restes connus** : l'objet poussé passe 0,2 s en physique au relâchement et peut glisser ; `BP_MovementMode_WalkingAST` (décélération instantanée en couverture) est porté mais non utilisé ; les os virtuels d'arme AST (`VB RHS_WeaponTrace`…) manquent au squelette (avertissements de compilation d'`OverlayGraph`, sans effet hors armes AST) ; la visée depuis la couverture (`UpdateCoverAim`) n'a pas été testée.
### 4.3 Autres systèmes de gameplay (ajouts spécifiques au projet)
```text
@@ -527,7 +552,24 @@ Content/Systems/
│
├── Movement/
│ ├── Climbing/AC_ClimbingComponent.uasset, CR_ClimbingGraphV2.uasset (Control Rig), CR_Mannequin_BasicFootIK.uasset, ClimbingMaterial.uasset
│ └── Cover/AC_Cover.uasset → ActorComponent : système de couverture (cover system). Générique (tout passe par `GetOwner`) : porté par `SandboxCharacter_CMC` ET, depuis le 2026-09-18, par `SandboxCharacter_Mover` (voir §4.2.2). Entrée/sortie de couverture sur la touche **P** gérée dans le composant lui-même ; `MoveAlongWall` fait un sphere trace le long du mur, `AddMovementInput` sur le pion et diffuse `OnEntreredCover` (InCover, direction `E_CoverD`, EdgeL/EdgeR).
│ ├── Cover/ → Système de couverture AST (copie du plugin AST_CoverSystem, §4.2.5). L'ancien `AC_Cover` a été supprimé par l'utilisateur.
│ │ ├── Blueprints/Components/BPC_CoverSystem.uasset → Composant cover : `FindCoverWall` (capsule trace devant le perso vers un `CoverWallActor`), montage d'entrée choisi par Motion Matching (`CHT_IdleToCover`), `CoverMovement` (déplacement le long de la spline), demi-tours (`CHT_TurnSide`), visée (`CHT_CoverAim`).
│ │ ├── Blueprints/Actors/CoverWallActor.uasset → Repère de couverture INVISIBLE sans collision bloquante (spline + SplineMesh QueryOnly), à poser ~10 cm devant un vrai mur ; `HighCover` = mur haut (debout) sinon bas (accroupi).
│ │ ├── Blueprints/Interfaces/BPI_CoverSystem, BPI_CoverWall ; Structs/S_CoverMontage, S_CoverAimChooserInput, S_IdleToCoverChooserInput
│ │ └── Character/Animation/ (HighCover/, LowCover/, Montages/, PSD_Cover, MotionMatchingData/CHT_*), Meshes/, Textures/
│ ├── Interaction/ → Système d'interaction AST (copie d'AST_InteractionSystem, §4.2.5).
│ │ ├── Blueprints/ActorComponent/BPC_Interaction.uasset → Composant : sphère de détection (90 uu) → objet le plus proche (`StateManager.ClosestActor`), `CheckInteraction` → MoveTo par montage (`CHT_MovetoInteraction`) puis montage d'action ; pousser/tirer (`Grab/Release PullPush Object`, overlay PULLPUSH).
│ │ ├── Actors/DoorActor, ElectronicDoorActor, CupboardActor, LeverActor, PullPushObject → Interactifs à poser dans les maps (leurs points d'interaction sont des ChildActor `BP_Door`/`BP_Cupboard`… de ASTShared/Inventory).
│ │ ├── Blueprints/Enums, Interfaces, Structs, Data/CHT_MovetoInteraction ; Character/AnimationNotify (InteractionEvent, ANS_TrackInteractionIKLocation, AN_GrabPullPushObje)
│ │ └── Character/Animations/ (Door, Cupboard, Lever, ElectronicDoor, MoveTo), Props/ (maillages porte/placard/levier)
│ ├── StateManager/ → Copie INTÉGRALE du plugin AST_StateManager (~565 assets) ; seule une partie sert (≈190 assets, §4.2.5). Le reste (cartes, caméras, poses d'armes, loot…) est candidat au nettoyage.
│ │ ├── Blueprints/ActorComponent/StateActorComponent + BPC_StateManager → Hub d'états AST (CoverState, InteractionState, OverlayState, entrées, ClosestActor…), cherché par les autres composants via GetComponentByClass/tags.
│ │ ├── Character/Animations/AnimationLayers/OverlayGraph (+ OverrideOverlayLayer) → calque lié (tag `Overlay`) : poses de couverture/pousser-tirer. `CanDynamicTransition` forcé à false (transitions ALS désactivées, §4.2.5).
│ │ ├── Character/Animations/AnimGraphs/InteractionIKGraph → calque lié : IK des mains pendant les interactions.
│ │ ├── Blueprints/Data/AST_GameplayTagDT, AST_StateTreeGameplayTagDT → tables de tags `AST.*` (déclarées dans DefaultGameplayTags.ini).
│ │ └── Inputs/IA_TakeCover (+ IMC_AST non utilisé)
│ ├── ASTShared/ → Sous-ensemble minimal (~44 assets) des plugins AST non portés, pour que StateManager/Interaction se chargent sans références cassées : Inventory/ (E_ItemType, BPI_ItemBase, BPI_InventorySystem, BP_InteractionActorBase + BP_Door/BP_ElectronicDoor/BP_Cupboard/BP_Lever/BP_PullpushObject, InteractionWidget), Melee/, NPC/ (BPI_AIController, EnemyDetectBS…), Parkour/ (interfaces, ParkourActor). Aucune logique de ces systèmes n'est active.
│ └── Test/L_ASTCoverTest.umap → Map de test : murs bas/haut + CoverWallActor, porte, porte électronique, placard, levier, objet à pousser ; GameMode GM_Dev.
│
├── Scent/BP_ScentPoint.uasset → Point émetteur d'odeur, spawné par `SandboxCharacter_CMC::ScentFunct` (toutes les 2s pendant que le joueur se déplace) et consommé par `AC_AnimalSenses::CheckScent` (Systems/Wildlife/, §4.4). (2026-09-05) Deux bugs corrigés à la réutilisation par la faune : (a) `ScentFunct` ne créait le point QUE via `SpawnActorFromClass`, sans jamais appeler son événement `Custom|Create(life)` — la durée de vie (`TimeToLife`) restait donc à 0 ; ajout d'un appel explicite `Create(life=20.0)` juste après le spawn. (b) Le décompte de durée de vie (`Custom|CustomEvent(DeltaTime)`) existait déjà mais n'était appelé par PERSONNE (`BeginPlay` enregistrait l'acteur auprès de `BP_TickManager` mais rien n'invoquait réellement l'event) — le point ne s'auto-détruisait donc jamais ; ajout d'un `EventTick` natif qui appelle directement ce Custom Event (évite de toucher au brancher `BP_TickManager` partagé, hors-scope). Comparaison de fin de vie durcie de `== 0` à `<= 0` (float exact-equality fragile). Aucune nouvelle logique d'odeur créée — uniquement réparation du mécanisme existant.
├── Movable_Object/BP_Moveble_Object.uasset → Objet physique déplaçable par le joueur
@@ -654,7 +696,43 @@ Content/Items/ → Objets ramassables/équipables du
└── ItemTextures/ → Textures d'icônes/inventaire communes à tous les items (T_*)
Content/PCG/ → Génération procédurale de contenu (plugin PCG)
├── Road/
├── Haussmann/ → (2026-10-30) Système PCG d'immeubles haussmanniens (Paris 2127, abandonnés depuis 60 ans). Doc complète :
│ │ `Docs/PCG_Haussmann.md`. Assemble les modules existants `/Game/ProjectF/Meshes/Facades|Facades_Variantes|Interieurs`
│ │ (SM_PF_HM_*, teintes MI_PF_HM_V_*_Gris/_Ocre), décor RueDeParis/PropsParis/Megascans ; aucun mesh nouveau
│ ├── Blueprints/BP_PF_Haussmann.uasset → Acteur : spline (façade ouverte, bâti à gauche, ou îlot fermé) + `PCG_Structure` (tag `HM_Structure`,
│ │ graphe PCG_PF_HM_Structure) + `PCG_Decoration`. Variables « PF » : `FacadeLength` (façade droite sans spline),
│ │ `Floors` (R+n), `BayWidth`, `BuildingBays`, `Depth`, `Degradation` (0..4), `Tint` (-1 = par immeuble), `bShopFront`.
│ │ Graine = Seed des composants (résultat reproductible, vérifié par empreinte)
│ ├── Graphs/PCG_PF_HM_Structure.uasset → Segments → pourtour (rue, cour, mitoyens) → travées/immeubles → étages → type par immeuble×étage →
│ │ ruine (colonnes effondrées, toitures perdues) → état par travée ; mansardes d'angle, chaînes d'angle,
│ │ planchers, terrasson zinc, souches, battants, gravats ; intérieurs : cage d'escalier (travée de porte cochère),
│ │ murs entre immeubles, appartements (refend rue/cour, cloisons, portes). ISM avec collision. Sa sortie alimente la décoration
│ ├── Graphs/PCG_PF_HM_Decoration.uasset → Lit la sortie de la structure (Get Actor Data, tag HM_Structure) : lierre, herbes, détritus, gravats
│ │ d'étage, enseignes ; sans collision. Générer la structure AVANT la décoration
│ │ Les deux graphes sont générés par script (`E:/projet/PF_Haussmann_Work/scripts/ue_hm_graph_*.py`) : les modifier là
│ ├── Data/ST_PF_HM_* + DT_PF_HM_*.uasset → Paramètres centralisés : DT_PF_HM_Levels (étages par Floors), DT_PF_HM_Degradation (H0-H4),
│ │ DT_PF_HM_Tints, DT_PF_HM_Types (type de module par Kind×Role), DT_PF_HM_Variants (mesh/matériau pondérés
│ │ par TypeId×teinte×dégradation), DT_PF_HM_LeafSlots (charnières des battants), DT_PF_HM_Tiles.
│ │ Source CSV unique : `E:/projet/PF_Haussmann_Work/scripts/hm_data_csv.py` (+ `ue_hm_data.py` pour réimporter)
│ └── Maps/L_PF_HaussmannTest.umap → Niveau de test non partitionné : 8 variantes (H0 à H4, R+4 à R+7, FacadeLength, îlot fermé, immeuble d'angle)
├── RoadNetwork/ → (2026-10-28/29) Système PCG de routes et ponts post-apo (France 2127). Doc complète : `Docs/PCG_RoutesPonts.md`
│ ├── Blueprints/BP_PF_Road.uasset → Route : spline + `PCG_Structure` (PCG_PF_Road_Structure) + `PCG_Decoration` (PCG_PF_Road_Decoration). Variables
│ │ `Profile` (Name, ligne de DT_PF_RoadProfiles), `Degradation` (0..3), `bSnapToLandscape`. Graine = Seed du composant PCG
│ ├── Blueprints/BP_PF_Bridge.uasset → Pont : spline (2 points) + PCG_PF_Bridge_Structure / _Decoration. `BridgeType`, `Degradation` (0..4),
│ │ `CollapsedSpan` (-1 = tirée par la graine), `bWalkable` (passerelle de fortune), `bVehicleTraversable` (barrage)
│ ├── Blueprints/BP_PF_RoadNetwork.uasset → Un par niveau : dalles de carrefour (PCG_PF_Network). Désactivé (couche JunctionPad vide) : les croisements sont faits par la variante J des routes
│ ├── Graphs/PCG_PF_*.uasset → Les 5 graphes (structure route, décoration route, structure pont, décoration pont, réseau). Générés par
│ │ script (`ProjetF blender/RoadNetwork/scripts/ue_rn_graph_*.py`) : les reconstruire par script plutôt qu'à la main
│ ├── Data/ST_PF_* + DT_PF_*.uasset → Paramètres centralisés : DT_PF_Variants (toutes les variantes pondérées par couche/famille/niveau),
│ │ DT_PF_RoadProfiles, DT_PF_Degradation (R0-R3, B0-B4), DT_PF_Bands (bandes latérales), DT_PF_BridgeTypes,
│ │ DT_PF_BridgeModules. Source CSV : `rn_data_csv.py` (+ `ue_rn_data.py` pour réimporter)
│ ├── Meshes/Road|Equipment|Bridge/ → Segments de route (7 profils × 8 variantes), carrefours, panneaux FR, bornes, J6, glissières (spline meshes de 4 m), blocs,
│ │ débris, modules de ponts (travées D0/D1/D2/effondrée, piles, culées, passerelle, barrage) — générés dans Blender
│ ├── Materials/ → M_PF_Road (couches par couleurs de sommets + marquages), M_PF_Structure (triplanaire), M_PF_Sign,
│ │ M_PF_DecalMesh (inutilisé : couche Decal désactivée) + Instances/MI_*
│ ├── Textures/ → T_PF_* (surfaces Fab/Megascans 2K, atlas de panneaux, masques de decals)
│ └── Maps/L_PF_RoadBridgeTest.umap → Niveau de test World Partition des 9 scénarios (terrain 1 km², rivière, ruisseau, vallée) + ses couches HLOD générées
├── Road/ → Prototype antérieur (une route, conservé tel quel, instance dans MapDev1). Remplacé par RoadNetwork/ pour les nouvelles routes
│ ├── PCG_Road.uasset → Graphe PCG générant la route procédurale (matériaux vieillis/mousse/humidité, potholes via GeometryScript)
│ ├── BP_AbandonedRoad.uasset → Acteur portant le graphe PCG
│ ├── M_Road.uasset, ST_Road_data.uasset, EM_Road_Type.uasset → Matériau, struct de données et enum de types de route
@@ -716,6 +794,27 @@ Content/Fab/ → Assets Fab/Quixel Megascans : MaterialFunctions
malgré 0 référenceur restant — laissé orphelin en l'état, sans danger). Toutes les références
(`BP_Item_Bow::ItemMesh_STATIC`, `DT_Items` ligne "Bow" → `Spawner Preview Mesh`) repointées vers
`survival_kit_bow_fixed`. Le socket `ArrowSocket` a dû être recréé (perdu avec l'ancien asset).
Content/KitFR/ → Kit modulaire de bâtiments français post-apo (généré dans Blender : `ProjetF blender/Kit_Habitat_FR.blend`,
export `UE_Export/Kit_FR`, import `kit_fr_scripts/ue_import_kit.py`). Meshes/<Style>/SM_FR_*_S0..S4,
3 maîtres M_KitFR_Opaque/Masked/Glass + Materials/Instances/MI_* , Textures/ (Megascans 2K + CC0).
**2026-10-28** : réimporté aux MÊMES chemins (niveaux non cassés) avec textures Megascans,
normales OpenGL → `flip_green_channel`, tuiles `TileSizeU/V`, AO branchée ; 88 anciennes textures
CC0 et 8 doublons `SM_FR_*_Floor_S0_001` supprimés. Dossier NON versionné dans git à cette date.
Content/ProjectF/ → **(2026-10-28)** Assets « Project F » (`ProjetF blender/ProjectF_Assets`, lots 1–5 + prototype, SANS les
véhicules) : Meshes/<Lot>/SM_PF_* (224, Nanite sauf meshes avec verre, UCX sinon collision complexe),
Maps/L_PF_Demo (présentation). Matériaux PRÉCALCULÉS dans Blender (`Scripts/pf_bake.py`) sur l'UV1 :
1 MI par asset de `M_PF_Baked` (BC + RMA = rugosité/métal/opacité + NO = normale espace OBJET,
Transform Local→World, donc indépendante des tangentes de l'UV0) ; verre `M_PF_BakedGlass`
(translucide) ; decal `M_PF_DecalCoulure` (masqué, UV0). Les slots papier peint/gravats/sombre
utilisent les MI de /Game/KitFR. Import : `ProjectF_Assets/Scripts/ue_import_pf.py`
(étapes textures → masters → mis → meshes). **Variantes** (précalculées aussi) : `MI_PF_<asset>_<Gris|Ocre>`
(teintes de pierre, 42 modules lot 2b) et `MI_PF_<asset>_<Sec|Humide>` (pièce sèche/infiltrée,
26 assets lot 4) — mêmes slots que la version par défaut : les appliquer en surcharge de matériau
sur l'instance placée (exemples dans L_PF_Demo, acteurs tagués `PF_VARIANTES`, script
`Scripts/ue_pf_demo_variants.py`).
Content/Bridges/ → Kits de ponts générés dans Blender (Truss, Bailey, Geo ; `ProjetF blender/UE_Export/README.md`) : travées D0-D3,
piles, culées, ponts entiers, un graphe PCG par kit. Le système PCG/RoadNetwork réutilise les travées Truss
(type `MetalAncien`). Dossier NON versionné dans git (2026-10-29).
Content/Megaplant_Library/ → Végétation Megaplant : Plant_Bilberry/, Tree_European_Aspen/, Tree_Hornbeam/
(chacun avec Instances/, Materials/, Textures/)
Content/Audio/Foley/ → **(2026-09-08)** Système de sons de pas/foley du sample Game Animation Sample :
@@ -783,6 +882,8 @@ Contenu du framework du sample conservé volontairement (déplacé le 2026-09-14
Ce projet est modifié via le plugin **VibeUE** (service MCP `unreal-mcp`, voir `.mcp.json`), qui expose des services Python (`unreal.BlueprintService`, `unreal.WidgetService`, `unreal.InputService`, `unreal.EnumStructService`, etc.) pour piloter l'éditeur Unreal sans l'ouvrir manuellement. Quelques pièges rencontrés et leurs solutions :
- **Contenu copié à la main depuis un autre projet/plugin (2026-09-27, port AST)** : les `.uasset` gardent leurs chemins d'origine (`/AST_…/`). Tant que ces chemins ne sont pas redirigés (`[CoreRedirects]` + redémarrage éditeur), NE PAS les charger : l'auto-save du MCP resauvegarde le Blueprint avec ses types perdus (c'est arrivé le 2026-09-21 à `BPC_StateManager`/`StateActorComponent`, restaurés depuis AST). Pour une spline d'acteur modifiée par script, mettre `spline_has_been_edited = True` sinon le script de construction repart des points du template. En Python, `unreal.Rotator(a, b, c)` = **(roll, pitch, yaw)** : toujours nommer les arguments.
- **PIÈGE — un nœud `Evaluate Chooser` sans objet de contexte branché renvoie TOUJOURS une liste vide (2026-09-18)** : constaté sur `SandboxCharacter_Mover_ABP::Update_MotionMatching`, dont les deux nœuds avaient leur pin de contexte (`SandboxCharacter_Mover_ABP_C`) laissé vide — aucune colonne du chooser ne pouvait être résolue, `ValidDatabases` restait vide en permanence et toute la branche Motion Matching de l'`AnimGraph` était inerte (`MM Search Cost` = FLT_MAX, `CurrentSelectedAnim` = None) sans qu'aucune erreur ne soit loguée. Toujours brancher `self` (type id créable : `Variables|Getareferencetoself`). Symptôme jumeau à surveiller : un chooser dupliqué dont on a changé le `ContextData` fonctionne, les liaisons se résolvant par NOM de variable sur la nouvelle classe de contexte.
- **PIÈGE — créer par script un sous-objet instancié dans un template de composant casse la sauvegarde des Blueprints ENFANTS (2026-09-17)** : `unreal.new_object(cls, outer=<template du composant>)` (ici un mode de mouvement ajouté à `CharacterMover.MovementModes`) produit un objet **privé** ; l'enfant (`SandboxCharacter_Mover_Ragdoll`, qui surcharge le composant via son `InheritableComponentHandler`) le prend comme archétype et sa sauvegarde échoue avec `Illegal reference to private object`. Préférer un enregistrement à l'exécution (`MoverComponent::AddMovementModeFromClass` au BeginPlay) ou l'édition manuelle dans l'éditeur.
- **PIÈGE — `SubobjectDataSubsystem.rename_subobject` juste après `BlueprintService.remove_component` provoque une assertion fatale (2026-09-17)** : `Renaming an object (…Arrow_GEN_VARIABLE) on top of an existing object (…Arrow1_GEN_VARIABLE) is not allowed` — l'ancien template n'est pas encore collecté. L'interpréteur Python est ensuite corrompu (`0xC0000005` au premier accès au Blueprint) et **le MCP sauvegarde les packages modifiés à chaque appel**, donc l'état intermédiaire peut se retrouver sur disque : redémarrer l'éditeur et vérifier le Blueprint (composants, liaisons) après ce type d'erreur. Corollaire : un composant ajouté par `BlueprintService.add_component(..., parent_name="Capsule")` reçoit un `ParentComponentOrVariableName` explicite qui déclenche l'avertissement `Reparenting the 'X' component … possible cyclic linkage` à chaque compilation ; l'ajouter sans parent (comme les autres composants racine du SCS) évite l'avertissement.
@@ -848,6 +949,30 @@ Ce projet est modifié via le plugin **VibeUE** (service MCP `unreal-mcp`, voir
- **Détecter des régressions d'assets binaires via git** : `git show <commit>:<fichier> | git lfs smudge` restitue l'ancien `.uasset` ; comparer l'ensemble des chaînes `/Game/...` (table des noms) entre ancienne et nouvelle version révèle les références perdues (lignes de chooser, bases d'un schéma, BPI d'un canal) sans ouvrir l'éditeur.
- **Déplacer un dossier via `AssetTools.rename_assets`** (liste d'`AssetRenameData`, un seul appel pour tout le lot) réécrit et sauvegarde lui-même les référenceurs, sans laisser de redirecteur quand tous sont chargeables (112 assets en ~32 s le 2026-09-14). Le coût dépend du nombre de référenceurs : un notify utilisé par des milliers d'animations oblige à toutes les réenregistrer.
**Pièges PCG et éditeur rencontrés sur `PCG/RoadNetwork` (2026-10-28/29, détail dans `Docs/PCG_RoutesPonts.md` §5)** :
- `EditorAssetLibrary.delete_asset` sur un asset encore tenu par Python (ex. un `PCGGraph` juste créé) échoue avec un message « in use » et un `ensure`, puis un `create_asset` du même nom ouvre une boîte modale « Overwrite Existing Object » qui bloque le MCP. Ne jamais supprimer puis recréer : recharger l'asset et le vider (`PCGGraph.remove_node` sur chaque nœud).
- `PCGGraph.add_edge` échoue **en silence** sur un nom de pin inexistant : vérifier les libellés (`node.input_pins[i].properties.label`). Pins utiles : `ModulesInfo` (sans espace), `Match Data`, `Projection Target`, `Input A`/`Input B`, `InsideFilter`/`OutsideFilter`, `Chosen`/`Discarded` ; les opérations unaires d'*Attribute Maths* ont un pin `In`, les binaires `InA`/`InB` (les deux doivent être branchés, même sur la même donnée).
- Opération unaire `SET` d'*Attribute Maths* : ne produit aucune sortie (aucune erreur) → utiliser *Copy Attributes*. *Match And Set Attributes* ne recopie pas la colonne de poids.
- *Get Spline Data* sur d'autres acteurs : `components_must_overlap_self` vaut vrai par défaut (on ne voit que ce qui chevauche l'acteur) et `bIgnoreSelfAndChildren` n'exclut pas la spline de l'acteur. *Distance* : utiliser `SourceShape`/`TargetShape = CENTER`, la distance par sphères englobantes est fausse sur des points de spline. Si la cible peut être vide, ajouter un point sentinelle très lointain.
- Le *Spline Sampler* en mode distance ne place pas de point à l'extrémité de la spline ; il ne lit pas la sortie d'*Offset Spline*. *Subdivide Spline* centre les points sur les modules et son attribut de taille est illisible par les opérations binaires.
- Les points de spline posés par Python sont réinitialisés quand le script de construction se relance : poser `bSplineHasBeenEdited = True` via `ObjectTools.set_properties`.
- Les collisions des ISM générés par PCG dans l'éditeur ne répondent aux rayons et au NavMesh qu'après rechargement du niveau.
- L'éditeur en arrière-plan tourne à environ 3 images/s : la génération PCG et `take_high_res_screenshot` attendent le premier plan (fenêtre amenée devant par script).
- `LandscapeService.get_height_at_location().height` ne renvoie pas une hauteur monde en cm : prendre la hauteur par `line_trace_single`.
- Monde partitionné ouvert par script : seuls quelques acteurs sont chargés ; `WorldPartitionBlueprintLibrary.load_actors(guids de get_actor_descs())` les charge tous.
**Pièges PCG supplémentaires rencontrés sur `PCG/Haussmann` (2026-10-30, détail dans `Docs/PCG_Haussmann.md` §5)** :
- *Copy Points* : `match_based_on_attribute` ne filtre pas (chaque source copiée sur chaque cible) → filtrer puis copier par valeur. En `TARGET_FIRST`, un attribut homonyme de la cible (même à sa valeur par défaut, après une fusion de données) écrase celui de la source → `SOURCE_FIRST` ou `seed_inheritance = RELATIVE`.
- *Merge* refuse les ensembles d'attributs → *Merge Attributes*. *Attribute Noise* (mode `SET`) exige que l'attribut existe déjà.
- *Spline To Segment* : tangentes seulement avec `extract_tangents` ; extrémité ouverte = angle 0 et tangente nulle ; dernier segment d'une spline ouverte : `SegmentNextIndex` = 0. *Subdivide Segment* : ⌊L / taille⌋ modules étirés, attributs transmis, mais pas de nouvelle graine (hacher une graine par module).
- *Match And Set* avec `match_attributes` : tirage pondéré parmi les lignes de même clé, piloté par la graine du point (même graine = même tirage, utile pour un tirage par groupe).
- Lire la sortie d'un autre composant PCG du même acteur : *Get Actor Data*, mode `GET_DATA_FROM_PCG_COMPONENT`, sélecteur de composant par tag (le graphe source doit brancher ses points sur sa sortie).
- `EnumStructService.add_struct_property` : type `FSoftObjectPath` (`SoftObjectPath` échoue sans erreur). Un import CSV de DataTable avec des « problems » ouvre une boîte modale « Message » qui bloque le MCP.
- Débogage : *Export Selected Attributes* (JSON) écrit les points d'un nœud dans un fichier ; reconstruire un graphe régénère tous les composants qui l'utilisent (le fichier est celui du dernier acteur).
---
## 10. Maintenir ce document à jour
@@ -887,3 +1012,6 @@ Ce document **doit toujours refléter l'état réel du projet**. Un skill dédi
- *2026-09-18 (suite) : à la demande de l'utilisateur, `SandboxCharacter_Mover_ABP` passe **entièrement en Motion Matching** — `Update_Logic` ne calcule plus la bascule, `AnimBranchIndex` est fixé à `0` (nœuds `Select` / `Not Equal (Enum)` / `AND` / `Get Stance` supprimés, valeur par défaut de la variable mise à 0). Diagnostic de la **T-pose en nage** : ce n'était pas l'ABP mais le contenu — 5 des 6 bases Pose Search de nage n'ont que des lignes à `AnimAsset = None` et la table `SwimmingInDeepIdle` du chooser est vide ; seul `PSD_SwimmingMoving` est rempli. Contournement dans `CHT_PoseSearchDatabases_Mover` (lignes vers bases vides neutralisées, lignes 13/16 élargies en MatchAny), détail et procédure de correction définitive en §4.2.2. Vérifié en PIE avec MM permanent : idle debout (`PSD_Relaxed_Stand_Idles`), course avant (`PSD_Relaxed_Stand_Run_F_Starts/Loops`), prone (`PSD_Dense_Prone_Idles` → `anim_Prone_Idle`), nage surface immobile / en mouvement et nage profonde (`PSD_SwimmingMoving` → `RM_Breastroke_overwater_01_right_turn_Retargeted`).*
- *2026-09-19 (système d'armes sur le Mover, voir §4.2.3) : `AC_Weapon::Equip/Unequip` reçoivent une branche `Cast Failed` → `SandboxCharacter_Mover` (leur `Cast To SandboxCharacter_CMC` échouait en silence sur le Mover, d'où `Weapon`/`isArmed` jamais renseignés). Nouvelle fonction `SandboxCharacter_Mover::SetEquippedWeapon` + variables `Weapon_Equip`/`WantToshot` sur le pion, `Weapon_Equip`/`Weapon_Equip Last Frame`/`Want Toshot` sur `SandboxCharacter_Mover_ABP` (alimentées dans `Update_PropertiesFromCharacter`, thread principal). `IA_Aim` renseigne `WantToshot`. `Update_MotionMatching` consulte aussi `CHT_PoseSearchDatabases_Mover` quand `Is Armed`, et `Get_MMInterruptMode` force l'interruption au changement d'arme. Dans `CHT_PoseSearchDatabases_Mover` : colonnes `Is Armed` et `IS Moving Object` réactivées, ligne 1 (« Stand Idles Bow ») passée en `Gait = MatchAny`. Testé en PIE de bout en bout (ramassage → main → anims arc → visée → tir) avec non-régression prone/nage. `Inventory_Equipper.uasset` apparaît modifié sans changement de contenu (resauvegarde automatique du MCP, mêmes références `/Game/`).*
- *2026-09-19 (MetaHuman en visual override, voir §4.2.4) : une première tentative mettait le corps MetaHuman directement comme mesh du pion (squelettes déclarés compatibles + sockets recopiées) ; elle a été **annulée** au profit de l'approche du sample GASP. Restauration de `ABP_GenericRetarget` depuis le commit initial (supprimé au nettoyage de la démo GASP), création de `IK_MetaHuman_test`, `RTG_UEFN_to_MetaHuman_test` et `BP_VisualOverride_MetaHuman` dans `Systems/Mover/VisualOverrides/`, `GM_Dev` reparenté sur `GM_Sandbox` (il était vide) et `VisualOverrides_Soft` renseigné, défaut du CVar `DDCvar.VisualOverride` passé de -1 à 0. Limite connue : les objets équipés restent accrochés au mannequin caché, ~12 cm d'écart avec la main du MetaHuman.*
- *2026-09-27 (port des systèmes AST Cover + Interaction, voir §4.2.5) : contenu AST copié sous `Systems/Movement/{Cover,Interaction,StateManager}` et réparé par `[CoreRedirects]` ; nouveau `Systems/Movement/ASTShared/` (dépendances minimales des autres plugins AST) et map de test `Systems/Movement/Test/L_ASTCoverTest` ; `SandboxCharacter_Mover` reçoit `BPC_StateManager`/`BPC_CoverSystem`/`BPC_Interaction` et les overrides de déplacement ; `SandboxCharacter_Mover_ABP` lie `OverlayGraph` et `InteractionIKGraph` ; `IMC_Sandbox` : A → `IA_TakeCover` ; tables de tags AST ajoutées à `DefaultGameplayTags.ini`. `AC_Cover` supprimé (par l'utilisateur).*
- *2026-10-28/29 : nouveau système `Content/PCG/RoadNetwork/` (routes et ponts post-apo, voir §7 et `Docs/PCG_RoutesPonts.md`), dossier racine `Docs/`, ligne `Content/Bridges/` ajoutée en §8, pièges PCG en §9. Le prototype `Content/PCG/Road/` est conservé tel quel. Aucun asset existant modifié ni supprimé (seul le dossier d'essai `RoadNetwork/_Spike`, créé et supprimé pendant le travail).*
- *2026-10-30 : nouveau système `Content/PCG/Haussmann/` (immeubles haussmanniens, voir §7 et `Docs/PCG_Haussmann.md` + `Docs/PCG_Haussmann_captures/`), pièges PCG ajoutés en §9 ; scripts hors projet dans `E:/projet/PF_Haussmann_Work/scripts`.*