Compare commits
10
Commits
f96d80301e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acaf1e564d | ||
|
|
d19df0a428 | ||
|
|
e829ff2808 | ||
|
|
8f6e6d5e31 | ||
|
|
83f553cef6 | ||
|
|
95f84aa7bb | ||
|
|
b2fe07180b | ||
|
|
ef85534eea | ||
|
|
66b88ade17 | ||
|
|
11de1ea556 |
No files matched your search
+343
-50
@@ -26,11 +26,11 @@ 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/`.
|
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.
|
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.
|
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.
|
||||||
|
|
||||||
En plus de cela, deux couches d'assets tiers volumineuses sont présentes mais **ne contiennent pas de logique de gameplay propre au projet** : le pack météo **UltraDynamicSky** (`Content/Systems/Weather/UltraDynamicSky/`) et diverses bibliothèques d'assets 3D Fab/Megascans/Quixel (`Content/Fab/`, `Content/Megaplant_Library/`, une bonne partie de `Content/Animations/` et `Content/Characters/`).
|
En plus de cela, deux couches d'assets tiers volumineuses sont présentes mais **ne contiennent pas de logique de gameplay propre au projet** : le pack météo **UltraDynamicSky** (`Content/Systems/Weather/UltraDynamicSky/`) et diverses bibliothèques d'assets 3D Fab/Megascans/Quixel (`Content/Fab/`, `Content/Megaplant_Library/`, une bonne partie de `Content/Assets/Animations/` et `Content/Characters/`).
|
||||||
|
|
||||||
### 1.3 Dépendances principales entre systèmes
|
### 1.3 Dépendances principales entre systèmes
|
||||||
|
|
||||||
@@ -85,6 +85,11 @@ Character (Pawn, géré par le framework "Sandbox Character")
|
|||||||
│ PAS l'enum directement — UserDefinedEnum non utilisable comme type de variable membre via les outils,
|
│ PAS l'enum directement — UserDefinedEnum non utilisable comme type de variable membre via les outils,
|
||||||
│ voir §9) configurée par arme sur le composant (1=Bow sur `BP_Item_Bow`, 4=Riffle sur
|
│ voir §9) configurée par arme sur le composant (1=Bow sur `BP_Item_Bow`, 4=Riffle sur
|
||||||
│ `BP_Item_AdvancedRifle`), convertie via `Utilities|Enum|BytetoEnumWeapon_Equip` avant d'être assignée.
|
│ `BP_Item_AdvancedRifle`), convertie via `Utilities|Enum|BytetoEnumWeapon_Equip` avant d'être assignée.
|
||||||
|
│ **Support du personnage Mover (2026-09-19)** : `Equip`/`Unequip` ne faisaient qu'un `Cast To
|
||||||
|
│ SandboxCharacter_CMC`. Sur `SandboxCharacter_Mover` (parent `Pawn`, aucune classe commune avec le CMC)
|
||||||
|
│ le cast échouait silencieusement → `Weapon`/`isArmed` jamais écrits, donc arme en main mais locomotion
|
||||||
|
│ toujours désarmée. Les deux fonctions ont désormais une branche `Cast Failed` → `Cast To
|
||||||
|
│ SandboxCharacter_Mover` → `SetEquippedWeapon(WeaponTypeByte)` (nouvelle fonction du pion Mover, voir §4.2.3).
|
||||||
│ **Bras armé qui reste bloqué en pose par défaut à l'équipement (2026-09-06, CORRIGÉ)** : deux causes
|
│ **Bras armé qui reste bloqué en pose par défaut à l'équipement (2026-09-06, CORRIGÉ)** : deux causes
|
||||||
│ distinctes cumulées, toutes deux dans `SandboxCharacter_CMC_ABP` :
|
│ distinctes cumulées, toutes deux dans `SandboxCharacter_CMC_ABP` :
|
||||||
│ (1) `Get_MMInterruptMode` (utilisée par `Update_MotionMatching` pour choisir le `PoseSearchInterruptMode`
|
│ (1) `Get_MMInterruptMode` (utilisée par `Update_MotionMatching` pour choisir le `PoseSearchInterruptMode`
|
||||||
@@ -99,7 +104,7 @@ Character (Pawn, géré par le framework "Sandbox Character")
|
|||||||
│ `Get_MMInterruptMode` (3ᵉ pin ajoutée au nœud `ORBoolean` existant via `add_node_pin`, PAS une réécriture
|
│ `Get_MMInterruptMode` (3ᵉ pin ajoutée au nœud `ORBoolean` existant via `add_node_pin`, PAS une réécriture
|
||||||
│ DSL complète — voir §9 pour le piège du wildcard enum). (2) Une fois l'interruption forcée, la recherche
|
│ DSL complète — voir §9 pour le piège du wildcard enum). (2) Une fois l'interruption forcée, la recherche
|
||||||
│ échouait quand même : `PSD_Dense_Stand_Bow_Idles`/`_Bow_Aim_Idles`/`PSD_Walk_Bow`/`PSD_Crouch_Bow`
|
│ échouait quand même : `PSD_Dense_Stand_Bow_Idles`/`_Bow_Aim_Idles`/`PSD_Walk_Bow`/`PSD_Crouch_Bow`
|
||||||
│ (toutes sous `/Game/Animations/humain/Armed_mov/Bow/`) avaient leur `PoseSearchMode` sur `PCAKD_TREE`
|
│ (toutes sous `/Game/Assets/Animations/humain/Armed_mov/Bow/`) avaient leur `PoseSearchMode` sur `PCAKD_TREE`
|
||||||
│ et leur build d'index échouait dès le chargement (`LogPoseSearch: Error: ... BuildIndex Failed because
|
│ et leur build d'index échouait dès le chargement (`LogPoseSearch: Error: ... BuildIndex Failed because
|
||||||
│ of 'No Convergence' while calculating PCA data`) — passées en `BRUTE_FORCE` (pas besoin de PCA, dataset
|
│ of 'No Convergence' while calculating PCA data`) — passées en `BRUTE_FORCE` (pas besoin de PCA, dataset
|
||||||
│ de toute façon minuscule), ce qui a débloqué la recherche. (3) **Lignes armées manquantes dans le
|
│ de toute façon minuscule), ce qui a débloqué la recherche. (3) **Lignes armées manquantes dans le
|
||||||
@@ -132,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.
|
│ 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/)
|
├─ 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)
|
├─ Composant AIPerceptionStimuliSourceComponent (2026-09-05)
|
||||||
│ └─ Ajouté sur SandboxCharacter_CMC pour que le joueur soit détectable par la vue de l'IA
|
│ └─ Ajouté sur SandboxCharacter_CMC pour que le joueur soit détectable par la vue de l'IA
|
||||||
@@ -195,6 +205,7 @@ Le suffixe `AGIS` sur beaucoup d'assets (`IA_InteractAGIS`, `WB_...AGIS`, foncti
|
|||||||
- **Nouvel objet d'inventaire (item)** → suivre le patron existant dans `Content/Items/` : un Blueprint `BP_Item_<Nom>` (héritant de `_BP_ItemBase` ou d'une base spécialisée dans `Items/BaseBlueprints/`), ses assets (mesh/matériau/texture) dans un sous-dossier `Content/Items/<Nom>/` ou `Content/Items/Resources/<Nom>/`, et une entrée dans `DT_Items` / les DataAssets sous `Content/Data/Inventory_Data/DataAssets/`.
|
- **Nouvel objet d'inventaire (item)** → suivre le patron existant dans `Content/Items/` : un Blueprint `BP_Item_<Nom>` (héritant de `_BP_ItemBase` ou d'une base spécialisée dans `Items/BaseBlueprints/`), ses assets (mesh/matériau/texture) dans un sous-dossier `Content/Items/<Nom>/` ou `Content/Items/Resources/<Nom>/`, et une entrée dans `DT_Items` / les DataAssets sous `Content/Data/Inventory_Data/DataAssets/`.
|
||||||
- **Nouvel Input Action lié à l'inventaire** → `Content/Systems/Inventory/Other/Inputs/Actions/`, mappé dans `IMC_AGIS_Character` ou `IMC_AGIS_InventoryTab`. **Input Action de déplacement/caméra générique** → `Content/Core/PlayerController/Input/`, mappé dans `IMC_Sandbox`.
|
- **Nouvel Input Action lié à l'inventaire** → `Content/Systems/Inventory/Other/Inputs/Actions/`, mappé dans `IMC_AGIS_Character` ou `IMC_AGIS_InventoryTab`. **Input Action de déplacement/caméra générique** → `Content/Core/PlayerController/Input/`, mappé dans `IMC_Sandbox`.
|
||||||
- **Nouveau widget d'inventaire** → `Content/UI/Inventory_UI/Widgets/`. **Nouveau widget hors inventaire** (HUD, menus) → `Content/UI/Widgets/`.
|
- **Nouveau widget d'inventaire** → `Content/UI/Inventory_UI/Widgets/`. **Nouveau widget hors inventaire** (HUD, menus) → `Content/UI/Widgets/`.
|
||||||
|
- **Nouvelle map de test** → `Content/Maps/DevTest/` (jamais dans le dossier du système testé). **Nouveau pack d'art du projet** (import Blender) → `Content/Assets/Environment/<Pack>/` ; **animations** → `Content/Assets/Animations/` (voir §8).
|
||||||
- Le clavier cible est **AZERTY** ; privilégier des touches identiques physiquement sur QWERTY/AZERTY pour les nouveaux raccourcis (ex. `V`, `B`).
|
- Le clavier cible est **AZERTY** ; privilégier des touches identiques physiquement sur QWERTY/AZERTY pour les nouveaux raccourcis (ex. `V`, `B`).
|
||||||
- Réplication réseau : toute action qui modifie l'état du jeu côté inventaire/stats doit suivre le patron `Request X SERVER` (Custom Event `...SERVER`, `Replicated From Client, Executes On Server`) déjà présent dans `Inventory_Player`.
|
- Réplication réseau : toute action qui modifie l'état du jeu côté inventaire/stats doit suivre le patron `Request X SERVER` (Custom Event `...SERVER`, `Replicated From Client, Executes On Server`) déjà présent dans `Inventory_Player`.
|
||||||
|
|
||||||
@@ -219,6 +230,8 @@ ProjectF/
|
|||||||
│
|
│
|
||||||
├── Config/ → Configuration moteur & jeu (voir détail §7)
|
├── Config/ → Configuration moteur & jeu (voir détail §7)
|
||||||
├── Content/ → Tous les assets du jeu (voir détail §3 à §6)
|
├── 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
|
├── Binaries/, Intermediate/, Saved/, DerivedDataCache/ → Générés par l'éditeur, exclus de Git, jamais à éditer/documenter
|
||||||
```
|
```
|
||||||
@@ -230,6 +243,7 @@ Quelques fichiers importants vivent directement sous `Content/`, hors de toute o
|
|||||||
```text
|
```text
|
||||||
Content/
|
Content/
|
||||||
├── Core/Character/SandboxCharacter_CMC.uasset → (déplacé depuis la racine le 2026-09-13) ⭐ Le Blueprint du PERSONNAGE JOUEUR lui-même (Character/Pawn). Référencé par GM_Dev, GM_Sandbox, PC_Sandbox, Gamemode_AGIS, WB_InventoryScreen, WBP_PauseMenu, BP_Moveble_Object, BP_Simply_Door, AC_PreCMCTick, AC_ClimbingComponent et son propre Anim BP (Systems/Blueprints/SandboxCharacter_CMC_ABP). C'est le point d'entrée central de tout le gameplay. Son EventGraph contient aussi : la détection de mort par chute (suivi tick de `IsFalling`/`FallStartZ`, calcul de hauteur à `OnLanded`, dégâts scalés via `AC_Stats.TakeDamage` au-delà de 300 unités, létal au-delà de 800) et une touche de debug K (InputDebugKey) qui force la mort via ce même `TakeDamage` — ajoutés le 2026-09-04.
|
├── Core/Character/SandboxCharacter_CMC.uasset → (déplacé depuis la racine le 2026-09-13) ⭐ Le Blueprint du PERSONNAGE JOUEUR lui-même (Character/Pawn). Référencé par GM_Dev, GM_Sandbox, PC_Sandbox, Gamemode_AGIS, WB_InventoryScreen, WBP_PauseMenu, BP_Moveble_Object, BP_Simply_Door, AC_PreCMCTick, AC_ClimbingComponent et son propre Anim BP (Systems/Blueprints/SandboxCharacter_CMC_ABP). C'est le point d'entrée central de tout le gameplay. Son EventGraph contient aussi : la détection de mort par chute (suivi tick de `IsFalling`/`FallStartZ`, calcul de hauteur à `OnLanded`, dégâts scalés via `AC_Stats.TakeDamage` au-delà de 300 unités, létal au-delà de 800) et une touche de debug K (InputDebugKey) qui force la mort via ce même `TakeDamage` — ajoutés le 2026-09-04.
|
||||||
|
├── Core/Character/SandboxCharacter_Mover.uasset + _Mover_Ragdoll.uasset → Personnage alternatif basé sur le plugin **Mover** (pion par défaut de `GM_Dev` ; en PIE c'est la variante `_Ragdoll` qui est possédée). Décrits avec le reste du framework Mover en §4.2.1, et leurs systèmes cover/prone/nage en §4.2.2.
|
||||||
├── Core/BP_GameInstance.uasset → (déplacé depuis la racine le 2026-09-13 ; `Config/DefaultEngine.ini` → `GameInstanceClass=/Game/Core/BP_GameInstance.BP_GameInstance_C`) GameInstance réellement utilisé par le projet (à ne pas confondre avec `Core/Coreinventory/GameInstance_AGIS`, la base du plugin — vérifier lequel des deux est configuré comme GameInstance par défaut avant de supposer que c'est l'un ou l'autre).
|
├── Core/BP_GameInstance.uasset → (déplacé depuis la racine le 2026-09-13 ; `Config/DefaultEngine.ini` → `GameInstanceClass=/Game/Core/BP_GameInstance.BP_GameInstance_C`) GameInstance réellement utilisé par le projet (à ne pas confondre avec `Core/Coreinventory/GameInstance_AGIS`, la base du plugin — vérifier lequel des deux est configuré comme GameInstance par défaut avant de supposer que c'est l'un ou l'autre).
|
||||||
└── Data/DT_DemoTags.uasset → (déplacé depuis la racine le 2026-09-13 ; l'export texte `DT_DemoTags.T3D` a été supprimé) ⚠️ **À NE PAS SUPPRIMER** : DataTable de gameplay tags du socle AGIS, déclarée dans `Config/DefaultGameplayTags.ini` (`+GameplayTagTableList=/Game/Data/DT_DemoTags`). Elle définit `General Inventory Slot` (indispensable à l'inventaire), `Human.*`, `Attachment.*` (singulier), `Flashlight.Battery`, `Other.*`, `Vehicle.*`. (Corrigé le 2026-09-13 : l'ancienne mention « aucune référence trouvée » était fausse — la référence passe par la config, invisible pour l'Asset Registry.) Dette connue : `DT_Items`, `Inventory_Player` et `AttachmentData_AdvancedRifle` utilisent `Attachments.*` (pluriel, tags inexistants → avertissements « Invalid GameplayTag »), antérieur au commit du 2026-09-04.
|
└── Data/DT_DemoTags.uasset → (déplacé depuis la racine le 2026-09-13 ; l'export texte `DT_DemoTags.T3D` a été supprimé) ⚠️ **À NE PAS SUPPRIMER** : DataTable de gameplay tags du socle AGIS, déclarée dans `Config/DefaultGameplayTags.ini` (`+GameplayTagTableList=/Game/Data/DT_DemoTags`). Elle définit `General Inventory Slot` (indispensable à l'inventaire), `Human.*`, `Attachment.*` (singulier), `Flashlight.Battery`, `Other.*`, `Vehicle.*`. (Corrigé le 2026-09-13 : l'ancienne mention « aucune référence trouvée » était fausse — la référence passe par la config, invisible pour l'Asset Registry.) Dette connue : `DT_Items`, `Inventory_Player` et `AttachmentData_AdvancedRifle` utilisent `Attachments.*` (pluriel, tags inexistants → avertissements « Invalid GameplayTag »), antérieur au commit du 2026-09-04.
|
||||||
```
|
```
|
||||||
@@ -267,11 +281,11 @@ Content/Core/
|
|||||||
├── PlayerController/ → Input générique du joueur (mouvement, caméra), indépendant de l'inventaire
|
├── PlayerController/ → Input générique du joueur (mouvement, caméra), indépendant de l'inventaire
|
||||||
│ ├── IA_InitiateClimb / IA_LeapFromClimb / IA_MovingClimb.uasset → Input Actions liées à l'escalade
|
│ ├── IA_InitiateClimb / IA_LeapFromClimb / IA_MovingClimb.uasset → Input Actions liées à l'escalade
|
||||||
│ └── Input/
|
│ └── Input/
|
||||||
│ ├── IMC_Sandbox.uasset → Input Mapping Context PRINCIPAL du personnage (mouvement, caméra, saut…)
|
│ ├── IMC_Sandbox.uasset → Input Mapping Context PRINCIPAL, ajouté dans `SetupInput` par `SandboxCharacter_CMC` ET (depuis le 2026-09-15) par `SandboxCharacter_Mover` (mouvement, caméra, saut, + actions AGIS : `IA_ToggleInventory` Tab, `IA_InteractAGIS`, `IA_QuickEquip/Select/GiveAGIS`, `IA_UseItemPrimary/SecondaryAGIS`). Mappings `IA_TriggerRagdoll` (R, X manette) et `IA_Takedown` (clic gauche, RT) ajoutés le 2026-09-15 pour le Mover ragdoll
|
||||||
│ └── IA_Move, IA_Look, IA_Jump, IA_Sprint, IA_Run, IA_Walk, IA_Crouch, IA_Prone, IA_Strafe,
|
│ └── IA_Move, IA_Look, IA_Jump, IA_Sprint, IA_Run, IA_Walk, IA_Crouch, IA_Prone, IA_Strafe,
|
||||||
│ IA_Aim, IA_Interact, IA_ESC, IA_NextPawn, IA_Traverse, IA_TeleportToTarget,
|
│ IA_Aim, IA_Interact, IA_ESC, IA_NextPawn, IA_Traverse, IA_TeleportToTarget,
|
||||||
│ IA_SwimmingDeep, IA_TwinStick_AimDirection, IA_Move_WorldSpace, IA_Look_Gamepad,
|
│ IA_SwimmingDeep, IA_TwinStick_AimDirection, IA_Move_WorldSpace, IA_Look_Gamepad,
|
||||||
│ IA_NextVisualOverride, IA_rool.uasset → Input Actions individuelles mappées dans IMC_Sandbox
|
│ IA_NextVisualOverride, IA_Takedown, IA_TriggerRagdoll, IA_rool.uasset → Input Actions individuelles mappées dans IMC_Sandbox. Aussi écoutées par la chaîne Mover (`SandboxCharacter_Mover`/`_Ragdoll`, `Systems/Mover/PC_Sandbox`, `Systems/Mover/SmartObjects/AC_SmartObjectAnimation`) ; le sprint du Mover écoute `IA_Run` (Started/Completed). `IA_rool` et `IA_Traverse` ne sont écoutés par aucun Blueprint
|
||||||
│
|
│
|
||||||
└── Tick/ → Système de gestion centralisée du Tick (perf)
|
└── Tick/ → Système de gestion centralisée du Tick (perf)
|
||||||
├── BPI_TickManager.uasset → Interface implémentée par les acteurs qui veulent être "tickés" par le manager
|
├── BPI_TickManager.uasset → Interface implémentée par les acteurs qui veulent être "tickés" par le manager
|
||||||
@@ -390,20 +404,20 @@ Copie du framework "Sandbox Character" du sample Epic **Game Animation Sample**,
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
Content/Systems/Mover/
|
Content/Systems/Mover/
|
||||||
├── SandboxCharacter_Mover.uasset → Personnage basé sur le plugin Mover (utilisé par aucune map du jeu ; le joueur réel est `Core/Character/SandboxCharacter_CMC`)
|
⚠️ (2026-09-18) `SandboxCharacter_Mover`, `_Ragdoll` (et l'ABP du CMC) vivent en réalité dans `Content/Core/Character/` — les deux lignes ci-dessous y correspondent, elles restent décrites ici pour garder le framework Mover d'un seul tenant.
|
||||||
├── SandboxCharacter_Mover_Ragdoll.uasset → Variante ragdoll du personnage Mover
|
├── SandboxCharacter_Mover.uasset → (dans `Content/Core/Character/`) Personnage basé sur le plugin Mover. (Vérifié le 2026-09-15) `GM_Dev` (GameMode de `MapDev1`) a `DefaultPawnClass = SandboxCharacter_Mover` ; en PIE sur `MapDev1` le pion obtenu est `SandboxCharacter_Mover_Ragdoll`. `SetupInput` ajoute `Core/PlayerController/Input/IMC_Sandbox` (même IMC que le CMC, inputs AGIS/inventaire compris) ; il porte aussi `Inventory_Player`, dont la propriété `Input Mapping Context` DOIT valoir ce même `IMC_Sandbox` (corrigé le 2026-09-15, elle valait `IMC_AGIS_Character`) : à la fermeture de l'inventaire, `WB_InventoryScreen.SwitchInput` fait `ClearAllMappings` puis ne ré-ajoute QUE cette variable — une mauvaise valeur coupe tous les contrôles (ZQSD, caméra) après fermeture. Même piège pour tout futur pion équipé d'`Inventory_Player`. Implémente `BPI_Interactable` depuis le 2026-09-17 (`GetTracePoint` = position/forward du composant `Camera`, comme `SandboxCharacter_CMC`) : sans cette interface, le trace d'interaction d'`Inventory_Player` (`Client Trace`, `Verify Trace`) part de (0,0,0) avec une direction nulle et aucun objet ne peut être ramassé. Tout futur pion équipé d'`Inventory_Player` doit aussi implémenter `BPI_Interactable::GetTracePoint`
|
||||||
├── SandboxCharacter_Mover_ABP.uasset → Anim Blueprint du Mover (utilise `Systems/Aiming/ABP_AimingMaster`)
|
├── SandboxCharacter_Mover_Ragdoll.uasset → Variante ragdoll du personnage Mover. ⚠️ C'est LUI le pion réellement possédé en PIE ; il surcharge le composant `CharacterMover` (ses propres `MovementModes`, dont `Ragdoll`) et `ProduceInput`/`On_MovementModeChanged_PostFinalize`. Toute modification du parent qui touche à ces éléments doit être vérifiée ici.
|
||||||
|
├── 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
|
├── 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 sample. ⚠️ Sa recherche de rebords ne marchait que sur les blocs de démo `LevelBlock_Traversable` : cette branche a été retirée le 2026-09-14 avec la démo, le Mover ne trouve donc plus aucun rebord (`TraversalCheckFailed`). Pour une vraie traversal, remplacer ce composant par `Systems/Blueprints/AC_TraversalLogic` (dette de convergence).
|
├── 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
|
├── 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)
|
├── 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`)
|
├── AnimModifiers/ → `AM_BakePhaseCurveFromFootstepNotifies`, `AM_FootSteps_Run` (référencés par quelques anims `UEFN_Mannequin`)
|
||||||
├── Cameras/ → `CameraAsset_SandboxCharacter`, `CameraDirector_SandboxCharacter`, `CHT_CameraRig`, `CameraShake_Basic`, `Rigs/CameraRig_*` (16)
|
├── Cameras/ → `CameraAsset_SandboxCharacter`, `CameraDirector_SandboxCharacter`, `CHT_CameraRig`, `CameraShake_Basic`, `Rigs/CameraRig_*` (16)
|
||||||
├── ControlRigs/CR_Biped_FootPlacement.uasset
|
├── ControlRigs/CR_Biped_FootPlacement.uasset
|
||||||
├── Data/ → Structs GASP (`S_CharacterPropertiesFor*`, `S_Traversal*`, `S_CHT_*` des choosers Mover/GetUp/Interaction, `S_Ragdoll*`, `S_MoverCustomInputs*`…), `Curve_RotationOffset_*`, `CHT_RotationOffsetCurve`, `BFL_HelpfulFunctions`, `BPI_InteractionTransform`
|
├── Data/ → Structs GASP (`S_CharacterPropertiesFor*`, `S_Traversal*`, `S_CHT_*` des choosers Mover/GetUp/Interaction, `S_Ragdoll*`, `S_MoverCustomInputs*`…), `Curve_RotationOffset_*`, `CHT_RotationOffsetCurve`, `BFL_HelpfulFunctions`, `BPI_InteractionTransform`
|
||||||
├── Input/ → `IMC_Sandbox` + 18 `IA_*` du Mover (anciennement `Content/Input/`), distincts de `Core/PlayerController/Input/`
|
├── MovementModes/ → `BP_MovementMode_Walking/Falling/Slide/Ragdoll`, `B_MovementMode_Flying`, `BP_MovementTransition_To/FromSlide`, **`BP_MovementMode_Swimming`** (2026-09-18). `BP_MovementMode_Walking` : la `Select` d'allure n'alimentait QUE Walk/Run/Sprint — les allures ajoutées (Prone, Swinning, SwinningSprint) donnaient vitesse ET accélération = 0 (personnage figé) ; ajout de la variable `ProneSpeed` (125) et câblage des entrées manquantes (prone → `ProneSpeed`/`WalkAcceleration`, nage → Walk/Run). `BP_MovementMode_Swimming` : enfant de `SimpleFlyingMode` (comme le mode vol), tag `Mover.IsSwimming`, `MaxSpeedOverride = 1` (l'entrée devient un pur vecteur d'intention) ; sa fonction `ComputeSwimTarget` lit le personnage propriétaire (cast `SandboxCharacter_Mover`) et produit la vitesse cible : en surface, Z = flottaison vers `WaterSurfaceZ - SurfaceOffset` (60) bornée par `MaxBobSpeed`, en plongée Z = intention caméra + `SwimVerticalInput` × `VerticalSpeed`, horizontal = intention × `SwimSpeed` (250) ou `SwimSprintSpeed` (450). ⚠️ Le `SwimmingMode` natif du plugin Mover (UE 5.8) n'est PAS utilisable : son `SimulationTick` est vide et rien n'alimente ses données d'eau (`CommonBlackboard::LastWaterResult`).
|
||||||
├── MovementModes/ → `BP_MovementMode_Walking/Falling/Slide/Ragdoll`, `B_MovementMode_Flying`, `BP_MovementTransition_To/FromSlide`
|
|
||||||
└── SmartObjects/ → `AC_SmartObjectAnimation` (version GASP, aussi utilisée par des STT de `Systems/Blueprints/`), `CHPA_SmartObject`, `PSS_SmartObject`, `Bench/`, `TasksAndConditions/STT_*`
|
└── SmartObjects/ → `AC_SmartObjectAnimation` (version GASP, aussi utilisée par des STT de `Systems/Blueprints/`), `CHPA_SmartObject`, `PSS_SmartObject`, `Bench/`, `TasksAndConditions/STT_*`
|
||||||
|
|
||||||
Content/Systems/Aiming/ → Système de visée développé dans Project_F : `ABP_AimingMaster`, `ABP_AimingMaster_UEFN` (aim offset), choosers `CH_AO`, `CH_Base_AO_Animechooser` (enum `Data/Enums/E_WaponType`)
|
Content/Systems/Aiming/ → Système de visée développé dans Project_F : `ABP_AimingMaster`, `ABP_AimingMaster_UEFN` (aim offset), choosers `CH_AO`, `CH_Base_AO_Animechooser` (enum `Data/Enums/E_WaponType`)
|
||||||
@@ -411,6 +425,123 @@ Content/Systems/Aiming/ → Système de visée développé da
|
|||||||
Content/Blueprints/AnimNotifies/ → SEUL reste de `Content/Blueprints/` : 23 notifies du sample (`BP_AnimNotify_FoleyEvent*`, `BP_NotifyState_EarlyTransition`, `_MontageBlendOut`, `_MMI_*`, `BP_AnimNotify_TriggerRagdoll`, `_OverrideMovementMode`…) liés à 1278 animations de `Characters/UEFN_Mannequin`. Laissés en place volontairement : les déplacer réenregistrerait 1,78 Go d'animations. Pour la plupart doublons de `Systems/Blueprints/AnimNotifies/`.
|
Content/Blueprints/AnimNotifies/ → SEUL reste de `Content/Blueprints/` : 23 notifies du sample (`BP_AnimNotify_FoleyEvent*`, `BP_NotifyState_EarlyTransition`, `_MontageBlendOut`, `_MMI_*`, `BP_AnimNotify_TriggerRagdoll`, `_OverrideMovementMode`…) liés à 1278 animations de `Characters/UEFN_Mannequin`. Laissés en place volontairement : les déplacer réenregistrerait 1,78 Go d'animations. Pour la plupart doublons de `Systems/Blueprints/AnimNotifies/`.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 4.2.2 Cover / prone / nage portés du CMC vers le personnage Mover (2026-09-18)
|
||||||
|
|
||||||
|
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` *(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** *(⚠️ 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`).
|
||||||
|
- **⚠️ Tick du personnage Mover (corrigé le 2026-09-18)** : `SandboxCharacter_Mover` et `_Ragdoll` avaient `PrimaryActorTick.TickInterval = 30 s` (le CMC est à 0). Tout leur `Event Tick` — `CacheInputsFromMover`, `Update_FloorValues`, `Update_ControlRotationRate`, `Update_SlidingAudio`, `Update_TargetedActor`, `Update_TwinStickMode`, `Update_SmoothedAnalogInputAmount`, `DebugDraws` — ne tournait donc qu'une fois toutes les 30 secondes (c'est ce qui empêchait la nage de se déclencher : `Update_Swimming` y était branchée). Intervalle remis à **0** sur les deux pions, et par sécurité `Update_Swimming` + `Update_Cover` ont été déplacées du `Event Tick` vers `On_PreSimulateTick` (délégué du `CharacterMover`, exécuté à chaque pas de simulation). Si un jour le tick de ces pions est de nouveau throttlé (politique `BP_TickManager`), la nage et la couverture continueront de fonctionner, mais les `Update_*` du framework GASP, eux, en souffriront.
|
||||||
|
- **⚠️ Bases Pose Search de nage vides → T-pose (contourné le 2026-09-18)** : sur les 6 bases de nage, **une seule est réellement remplie**, `Animations/humain/SwimmingAnimation/Swimming_animation/Breastok/surface/PSD_SwimmingMoving` (5 clips de brasse en surface). `PSD_SwimmingIdle`, `PSD_SwimmingMovingSprint`, `PSD_SwimmingDeepIdle`, `PSD_SwimmingDeepMoving`, `PSD_SwimmingDeepMovingSprint` ont des lignes dont l'`AnimAsset` est **None** (log : `OnGetComplete - Database None entry N has no associated animation asset`), et la table imbriquée `SwimmingInDeepIdle` du chooser n'a **aucun résultat**. L'ABP étant désormais 100 % Motion Matching, une base vide = aucune pose = **T-pose**, exactement le bug remonté. Contournement appliqué dans `CHT_PoseSearchDatabases_Mover` : les lignes qui pointent sur une base vide (12, 14, 15, 17) sont rendues inatteignables (`Stance = Prone` alors que `Movement Mode = Swimming`, combinaison impossible par construction) et les deux lignes qui pointent sur `PSD_SwimmingMoving` (13 pour Swinning, 16 pour SwinningDeep) passent `Movement State` et `Gait` en **MatchAny** pour couvrir tous les cas de nage. Vérifié en PIE : nage de surface immobile, nage de surface en mouvement et nage profonde sélectionnent bien `RM_Breastroke_overwater_01_*`.
|
||||||
|
- **Vraie correction à faire à la main** (impossible par script : la propriété `DatabaseAnimationAssets` d'un `PoseSearchDatabase` et le `ResultsStructs` d'un `ChooserTable` ne sont exposés ni au Python d'UE ni à `ObjectTools.set_properties` — seules `columnsStructs`/`contextData` le sont) : ouvrir chaque base vide et y glisser les clips qui existent déjà sous `Animations/humain/SwimmingAnimation/` — `IDLE/IP_idle_underwater_01_Retargeted` + `IDLE/RM_Idle_turn_*` pour `PSD_SwimmingIdle`, `Swimming_animation/Crawl/RM_Crawl_*` pour `PSD_SwimmingMovingSprint`, `Swimming_animation/Breastok/RM_Breastroke_underwater_*` pour `PSD_SwimmingDeepIdle/Moving/MovingSprint` — puis remettre les lignes 12/14/15/17 du chooser sur leur `Stance` d'origine (3, 3, 4, 4) et donner un résultat à la table imbriquée `SwimmingInDeepIdle`.
|
||||||
|
- **Restes connus** : le cover du Mover joue les anims accroupies GASP, pas les bases de couverture du CMC (`PSD_Dense_Crouch_Idles_CoverLeft/Right`) ni le nœud `Mirror` de l'AnimGraph du CMC ; en couverture le personnage conserve un écart d'orientation d'une dizaine de degrés par rapport au mur (orientation strafe qui converge lentement).
|
||||||
|
|
||||||
|
#### 4.2.3 Système d'armes porté sur le personnage Mover (2026-09-19)
|
||||||
|
|
||||||
|
Ce qui marchait déjà sur le Mover avant cette session (vérifié en PIE) : le ramassage (`IA_InteractAGIS`), le rangement au dos (socket `SpineRifle`), le passage en main par la roue V/B (`IA_QuickSelectAGIS` / `IA_QuickEquipAGIS` → socket `Rifle`), l'appel de `AC_Weapon::Equip`/`Unequip` via `HandleHeldStateChanged`, et le tir (`IA_UseItemPrimaryAGIS` → `Inventory_Player::UseHeldPrimarySERVER` → `BP_Item_AdvancedRifle::EventPrimaryUse`). `Inventory_Equipper` est générique : son `OwnerMesh` se résout bien sur le composant `SkeletalMesh` du Mover.
|
||||||
|
|
||||||
|
Ce qui ne marchait PAS et a été corrigé :
|
||||||
|
|
||||||
|
- **`AC_Weapon` ne parlait qu'au CMC** : `Equip`/`Unequip` faisaient un `Cast To SandboxCharacter_CMC`, qui échoue sur le Mover (`Pawn` vs `Character`, aucune classe commune). Résultat : arme bien en main, mais `Weapon` et `isArmed` jamais écrits → locomotion désarmée en permanence. Une branche `Cast Failed` → `Cast To SandboxCharacter_Mover` a été ajoutée dans les deux fonctions ; le CMC est inchangé.
|
||||||
|
- **Nouvelle fonction `SandboxCharacter_Mover::SetEquippedWeapon(WeaponTypeByte)`** (appelée par `AC_Weapon`, `0` = déséquipement) : écrit `Weapon_Equip` (nouvelle variable, enum `Weapon_Equip`), `isArmed` (= byte ≠ 0), `WantToshot` (remis à false au déséquipement) et `Weapon`. ⚠️ **Trois enums d'arme coexistent dans le projet** : `Weapon_Equip` (None/Bow/OneArmPistol/TwoArmPistol/Riffle/Bat — c'est l'espace de `AC_Weapon::WeaponTypeByte` et des colonnes du chooser de locomotion), `E_WaponType` (None/Riffle/Pistoll/Bow — c'est le type de `SandboxCharacter_Mover::Weapon` et du champ `S_CharacterPropertiesForAnimation.Weapon_Type`, lu par les choosers d'aim offset de `Systems/Aiming/`) et `E_WeaponType` (inutilisé ici). `SetEquippedWeapon` fait donc la conversion 1(Bow)→3, 2/3(Pistol)→2, 4(Riffle)→1, reste→0.
|
||||||
|
- **IA_Aim renseigne `WantToshot`** (nouvelle variable du pion) : `WantToshot = ActionValue AND isArmed` sur `Triggered`, remis à `false` sur `Completed`. C'est ce bool que lit la colonne « Want Toshot » du sous-chooser `Stand Idles Bow` pour passer de l'idle arc à l'idle arc en visée.
|
||||||
|
- **`SandboxCharacter_Mover_ABP` reçoit l'état d'arme** : nouvelles variables `Weapon_Equip`, `Weapon_Equip Last Frame`, `Want Toshot` (+ `Is Armed` et `IS Moving Object` déjà présentes), toutes alimentées en fin de `Update_PropertiesFromCharacter` (**thread principal**, comme le CMC le fait dans son `EventBlueprintUpdateAnimation` — surtout pas dans `Update_Logic`, qui peut tourner en thread-safe update).
|
||||||
|
- **`Is Armed` de l'ABP = `isArmed` ET `Weapon_Equip == Bow`** — *stopgap assumé* : l'arc est la SEULE arme qui possède des bases Motion Matching armées (`PSD_Dense_Stand_Bow_Idles`, `_Bow_Aim_Idles`, `PSD_Walk_Bow`). Sans cette condition, un fusil mettait `Is Armed = true`, les lignes 0/2 du chooser (`MatchFalse`) étaient rejetées, les lignes arc 1/3 échouaient sur leur colonne `Weapon_Equip`, et on retombait sur la ligne 18 « Push » (ou sur rien du tout). Avec la condition, fusil/pistolet jouent proprement la locomotion désarmée, arme en main. À retirer le jour où des bases fusil existeront.
|
||||||
|
- **`Update_MotionMatching`** : le chooser `CHT_PoseSearchDatabases_Mover` n'était consulté que si `Stance` ∉ {Stand, Crouch} (prone/nage). La condition devient `(Stance ≠ Stand ET ≠ Crouch) OU Is Armed`, sinon les lignes arc — qui sont des lignes *debout* — n'étaient jamais atteintes. La sortie `False` du Branch est en plus reliée à `SetDatabasesToSearch` pour que les deux chemins poussent bien leur liste dans le nœud MM.
|
||||||
|
- **`Get_MMInterruptMode`** : ajout du terme `Weapon_Equip ≠ Weapon_Equip Last Frame` sur le `OR` racine. Sans lui, changer d'arme ne forcçait aucune interruption : Motion Matching gardait la pose continue (anim désarmée) et ne basculait jamais sur la base arc, même une fois celle-ci dans la liste (coût de continuité toujours plus bas). C'est le même piège que celui décrit en §1.3 pour le CMC.
|
||||||
|
- **`CHT_PoseSearchDatabases_Mover`** : colonne `Is Armed` **réactivée** (elle avait été désactivée le 2026-09-18 faute de propriété correspondante sur l'ABP Mover), colonne `IS Moving Object` réactivée aussi (sinon la ligne 18 « Push » devient un attrape-tout qui remporte tous les cas debout non couverts), et **ligne 1 (« Stand Idles Bow ») : colonne `Gait` passée de `MatchEqual Walk` à `MatchAny`**. C'était le dernier blocage : l'allure par défaut du personnage est `Run`, donc la ligne arc ne pouvait jamais matcher à l'arrêt. (Le même défaut existe dans `CHT_PoseSearchDatabases_Dense` côté CMC, non corrigé ici.)
|
||||||
|
|
||||||
|
Vérifié en PIE, dans cet ordre : ramassage du fusil → dos ; V+B → main + `Weapon = Riffle`, `Weapon_Equip = Riffle`, `isArmed = true` côté pion ET côté ABP ; locomotion désarmée propre avec le fusil en main (pas de T-pose) ; arc → `PSD_Dense_Stand_Bow_Idles` → `StandingIdle01_UE_Anim3` ; arc + clic droit → `Want Toshot = true` → `PSD_Dense_Stand_Bow_Aim_Idles` ; arc en course → repli propre sur `PSD_Dense_Stand_Run_Loops` ; clic gauche → `EventPrimaryUse` du fusil (qui refuse de tirer faute de chargeur équipé — comportement normal, non lié au Mover) ; non-régression prone (`PSD_Dense_Prone_Idles`) et nage (`PSD_SwimmingMoving`).
|
||||||
|
|
||||||
|
**Correctif 2026-10-31 — « je ramasse le fusil mais B ne l'équipe pas »** :
|
||||||
|
- `Inventory_Player::ToggleQuickEquip` (touche **B**) n'équipait que le slot choisi au préalable avec **V** (`WB_QuickSelect` fait `CycleQuickSlot` à chaque ouverture, donc chaque appui sur V avance d'un slot). Sans sélection (`SelectedQuickSlot = 0`), B affichait « Aucun item selectionne ». Désormais, slot 0 → `SelectQuickSlot(1)` (Arme 1) puis le chemin normal `GetQuickSlotItemInfo` → `SwitchWeaponByUID`. V reste le moyen de choisir un autre slot.
|
||||||
|
- Supprimé de `SandboxCharacter_Mover` l'événement **`Debug Key B`** (20 nœuds) : il faisait tourner `Weapon` (Riffle → Pistoll → Bow → None) et écrivait `isArmed` à chaque appui sur B, en concurrence directe avec l'équipement.
|
||||||
|
- Vérifié en PIE : E (dos, `SpineRifle`) → B (main, `Weapon_Equip = Riffle`, `isArmed = true`) → B (rangé) → B (ressorti).
|
||||||
|
|
||||||
|
**Correctif 2026-10-31 — fusil tenu à une main, bras ballant, aucune pose de visée** :
|
||||||
|
- L'overlay AST (`OverlayGraph`, états `SMG Relaxed / Combat / Aim`…) tire ses poses de `BPFL_AST::GetOverlayAnimSet`, qui interroge le **GameInstance** via l'interface `BPI_ASTGI`. Aucune classe du projet ne l'implémentait → `overlay Anim Set` vide → overlay neutre, quel que soit l'`OverlayState`. Conséquence en cascade : au rangement du 2026-10-30, `DA_QuickSetupSettings` et presque toutes les poses de `Poses/OverlayPoses/` semblaient orphelins et avaient été supprimés.
|
||||||
|
- Restaurés (sauvegarde `ProjectFv1_backup_reorg_2026-10-30`, struct depuis `ProjectFv1_backup_ast_port_2026-09-27`) : `StateManager/QuickSetup/DA_QuickSetupSettings`, `Blueprints/Data/PDA_QuickSetupSettings`, `Blueprints/Structs/S_QuickSetupVariables`, les poses `OverlayPoses/{Default,DefaultMelee,Submachinegun,Handgun,SniperRifle,Bullpup,Longshotgun}Poses`, et 14 montages `Character/Animations/Melee/*_Montage` référencés par le DA. ⚠️ Ces montages de mêlée sont **incomplets** (anims, sons et notifies AST Melee jamais portés) : à ne pas jouer tant que la mêlée n'est pas portée.
|
||||||
|
- `BP_GameInstance` implémente `BPI_ASTGI` : variable `QuickSetupSettings` (= `DA_QuickSetupSettings`) et `Get Overlay Animset` renvoie `QuickSetupVariables.OverlayAnimationSet`. Les trois autres fonctions de l'interface (mêlée, parkour, effets) restent vides.
|
||||||
|
- `SandboxCharacter_Mover`, graphe `CameraCh`, `IA_Aim` : `Triggered` → `BPC_StateManager::SetInputAim(ActionValue AND isArmed)`, `Completed` → `SetInputAim(false)`. C'est ce qui passe `RotationState` à `Aim` et fait entrer l'overlay dans l'état `… Aim`. Au relâchement, AST remet `DefaultRotationState` (= `Strafe`), pas `Orient`.
|
||||||
|
- Vérifié en PIE : équipé → les deux mains tiennent le fusil (pose SMG relâchée) ; clic droit maintenu → fusil épaulé, pointé devant.
|
||||||
|
|
||||||
|
**Correctif 2026-10-31 — main gauche à côté du fusil en visée** :
|
||||||
|
- `WeaponIKGraph` pose les mains par `TwoBoneIK` vers des os virtuels AST (`VB RHS_ik_hand_l`, `VB LHS_ik_hand_r`) absents de notre squelette → IK sans effet. Ajoutés à `SK_UEFN_Mannequin` sous les noms `VB hand_r_ik_hand_l` / `VB hand_l_ik_hand_r` (Python ne peut pas les renommer) et `TwoBoneIK_2` (main droite) repointé dessus.
|
||||||
|
- **Comment AST tient une arme** (lu dans `E:\AST_V1_17`) : même squelette `SK_UEFN_Mannequin` que nous (`RHS`/`LHS` ne sont pas des os, juste des os virtuels renommés `hand_r→ik_hand_l` etc.). L'arme s'attache à un **socket par famille sur `hand_r`** (`SMG`, `Shotgun`, `Shotgun1`, `Pistol`, `PistolL`), et la main gauche vient **uniquement de l'animation** (`ik_hand_l` relatif à `hand_r`) : le socket `OffHandIK` des armes AST et `BPI_Firearm::GetLeftHandIKBone` ne sont appelés nulle part. Vérifié : l'`OffHandIK` de `SKM_SMG` tenue au socket `SMG` tombe à 2 cm du `ik_hand_l` de `SMG_Aim_Pose`.
|
||||||
|
- **Socket `Rifle` recalé sur le socket AST `SMG`** (2026-10-31) : orientation = celle de la SMG AST (canon de `SKM_SMG` sur +Y, du nôtre sur +X → lacet de 90°), position choisie pour garder notre point de prise main droite. Nouveau : loc (-21.90, 11.28, 4.74), rot (P -4.60, Y 158.94, R 0.98) ; ancien : loc (-24.56, 3.89, 3.31), rot (P -7.83, Y 177.40, R 0). L'ancien socket faisait pointer le canon ~20° à côté de la direction de visée des poses AST.
|
||||||
|
- **Main gauche** (`TwoBoneIK_0` et `_5`) : cible `VB hand_r_ik_hand_l` (orientation de prise de l'anim, `Take Rotation From Effector Space`) + offset en espace os (1.25, -4.96, -4.88), qui met le poignet au point (11, -6, 7) de `SM_RifleAdvanced` = bord supérieur gauche du garde-main. La pose AST est une prise par-dessus (dos de la main en haut, doigts sur le flanc) : un poignet à mi-hauteur laissait la main pendre sous le garde-main. Mesuré : 0 cm en visée, 0,9 cm en pose relâchée. ⚠️ Calé sur ce fusil ; une autre arme demandera son socket et son offset. Ne pas cibler `hand_r` + offset (la main hérite de l'orientation de la main droite). Le socket `LH_IK` du mesh, lui, n'est utilisé par rien.
|
||||||
|
- `ANS_WeaponTransformCorrection` (notify des montages d'équipement AST) ramène l'arme de l'**inventaire AST** (composant tagué `InventorySystem`) vers une transform relative nulle. Notre pion utilise AGIS → arme `None` → ~940 « Accessed None » par session. Ajout d'un `IsValid` sur `Weapon` avant `SetActorRelativeTransform` : no-op chez nous (AGIS attache déjà le fusil pile sur le socket), inchangé si un inventaire AST est présent. Vérifié : 0 erreur Blueprint sur équiper/ranger/rééquiper/viser.
|
||||||
|
- Restant : `OverlayGraph`, `OverrideOverlayLayer`, `BoneTrackPoint`, `InteractionControlRig`, `WeaponCollisionControlRig` référencent encore les noms d'os virtuels AST ; pas de socket AST pour pistolet/fusil à pompe tant qu'on n'a qu'un fusil.
|
||||||
|
|
||||||
|
**Correctif 2026-10-31 — mains et doigts du MetaHuman (ce qu'on voit vraiment)** : le MetaHuman visible n'est qu'une copie par retarget du mannequin caché, qui porte l'arme et l'IK (voir §4.2.4). Trois défauts dans `Systems/Mover/VisualOverrides/` :
|
||||||
|
- `IK_MetaHuman_test` n'avait **aucun goal ni solveur** (les chaînes `LeftArm`/`RightArm` pointaient vers des goals `LeftHandIK`/`RightHandIK` inexistants) → l'op « Retarget IK Goals » ne faisait rien et les mains du MetaHuman tombaient ~17 cm à côté de celles du mannequin (bras plus longs, épaules plus hautes). Ajoutés : goals `LeftHandIK` (`hand_l`) et `RightHandIK` (`hand_r`) + un `IKRigLimbSolver` par bras (racine `upperarm_l`/`_r`). Pieds non touchés (toujours FK).
|
||||||
|
- `RTG_UEFN_to_MetaHuman_test`, op « Retarget IK Goals » : `LeftArm`/`RightArm` en `BlendToSource = 1` (rotation laissée à 0 : la rotation brute du mannequin n'apporte rien et ignore les écarts de pose de référence) → mains du MetaHuman exactement sur celles du mannequin (écart mesuré < 0,1 cm), donc sur l'arme. `ABP_GenericRetarget` peut encore moduler ce réglage avec les courbes `Retarget_Hand_L/R_BlendToSource` (Lerp vers 1, donc sans effet ici).
|
||||||
|
- Doigts : chaînes doigts + métacarpes de l'op « FK Chains » en `OneToOne`, et **pose de retarget du MetaHuman auto-alignée (`ChainToChain`) sur les 30 os de doigts**. Avant, la flexion des doigts de l'anim se perdait (index 2° au lieu de 24°) parce que les poses de référence des deux squelettes ne concordaient pas.
|
||||||
|
- Vérifié en PIE : en visée, doigts gauches et droits fléchis comme sur le mannequin ; au repos, bras et mains naturels.
|
||||||
|
|
||||||
|
**Correctif 2026-10-31 — état d'overlay écrasé à l'initialisation** : `OverlayGraph::BlueprintInitializeAnimation` réécrivait `Overlay State` avec `GetStartWeaponOverlayState` du composant d'inventaire AST, que notre pion n'a pas → `None` à chaque init. Il lit désormais `StateManager` (cast en `StateActorComponent`) → `GetOverlayState`.
|
||||||
|
|
||||||
|
**Équipement de départ (test)** : `Inventory_Player` du `SandboxCharacter_Mover` a `Initial Items` = `Rifle` ×1, `Magazine` ×1, `Ammo1` ×60 → au spawn, fusil sur le dos (`SpineRifle`), **B** pour le prendre en main. Piège AGIS : les `Items` posés dans les conteneurs d'un `InventoryData` (DataAsset) **ne sont pas chargés** ; seul `Initial Items` passe par `LoadSubItem` (graphe `INITIALIZATION` de `Inventory__Main`), comme le casque de `BP_Deadman`. À vider avant une build de jeu.
|
||||||
|
|
||||||
|
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` 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)
|
||||||
|
|
||||||
|
Approche retenue (celle du sample GASP, cf. la vidéo de référence) : **le mannequin UEFN reste le mesh du pion et porte toute l'animation ; le MetaHuman est un acteur enfant qui le recopie par retarget IK.** Le mesh du pion est simplement rendu invisible. Avantage : rien ne change côté Motion Matching, sockets, prone/nage, ragdoll — et on peut changer de « peau » à chaud.
|
||||||
|
|
||||||
|
Le pipeline existait déjà dans le projet mais était **incomplet** : `SandboxCharacter_Mover` a son `ChildActorComponent` `VisualOverride` (tagué `VisualOverride`) et son `AC_VisualOverrideManager`, mais tous les acteurs de skin du sample (`BP_Manny`, `BP_Quinn`, `BP_Echo`, `BP_Twinblast`, `BP_UE4_Mannequin`) **et l'AnimBP qui les pilote** avaient été supprimés au nettoyage de la démo GASP.
|
||||||
|
|
||||||
|
Assets créés / restaurés, tous dans `Content/Systems/Mover/VisualOverrides/` :
|
||||||
|
|
||||||
|
- **`ABP_GenericRetarget`** — récupéré du commit initial (`538ebd2a`). C'est un **Animation Blueprint Template** (`bIsTemplate`, donc sans squelette cible : utilisable sur n'importe quel mesh). Son AnimGraph tient un seul nœud `Retarget Pose From Mesh` ; son `EventBlueprintUpdateAnimation` choisit l'`IKRetargeter` dans la map `IKRetargeter_Map` **en utilisant le premier Component Tag du composant qui l'héberge** comme clé. La map garde ses entrées d'origine (toutes à `None`, les retargeters du sample ayant été supprimés) plus la nôtre.
|
||||||
|
- **`IK_MetaHuman_test`** — IK Rig sur `/Game/Characters/MEtahuman/Unpacked/test/Body/SKM_test_BodyMesh`, généré par `IKRigController.apply_auto_generated_retarget_definition()` (l'auto-caractérisation reconnaît le squelette MetaHuman : bassin = `pelvis`, 29 chaînes standard).
|
||||||
|
- **`RTG_UEFN_to_MetaHuman_test`** — source `IK_UEFN_Mannequin`, cible `IK_MetaHuman_test`. `auto_map_chains(EXACT)` mappe tout sauf deux chaînes, l'auto-caractérisation MetaHuman nommant `LeftFoot`/`RightFoot` ce que le mannequin appelle `LeftToe`/`RightToe` — mappées à la main.
|
||||||
|
⚠️ **`add_default_ops()` ne crée PAS l'op des chaînes IK.** La pile par défaut est Pelvis Motion / FK Chains / Run IK Rig / Root Motion / Remap Curves ; or `ABP_GenericRetarget::UpdateRetargetProfile` va chercher l'op **nommée « Retarget IK Goals »** (`GetOpControllerFromRetargetProfile` → cast vers `IKRetarget_IKChains_Controller`) pour moduler l'alpha d'IK par chaîne. Sans elle, le cast renvoie None et `SetSettings` spamme un *Blueprint Runtime Error* à chaque frame. Correctif : `add_retarget_op("/Script/IKRig.IKRetargetIKChainsOp")` — le **chemin de classe complet est obligatoire**, le nom court est refusé (retourne -1). L'op arrive déjà nommée « Retarget IK Goals » et se place juste avant « Run IK Rig » ; il faut ensuite refaire `assign_ik_rig_to_all_ops` + `auto_map_chains` (les mappings de chaînes sont **par op**). Résultat : 4 chaînes IK (LeftLeg, LeftArm, RightLeg, RightArm), plus aucune erreur en PIE.
|
||||||
|
- **`BP_VisualOverride_MetaHuman`** — Actor : `Body` (racine, `SKM_test_BodyMesh`, `AnimClass = ABP_GenericRetarget_C`, **Component Tag `RTG_UEFN_to_MetaHuman_test`**) → `Face` (`SKM_test_FaceMesh`, `ABP_Face_C`) ; plus un `MetaHumanComponentUE` (`BodyComponentName = "Body"`, `FaceComponentName = "Face"`, post-process `ABP_Clothing_PostProcess`). Pas de grooms : ce MetaHuman n'en a aucun d'assigné.
|
||||||
|
|
||||||
|
Câblage de la sélection :
|
||||||
|
|
||||||
|
- `GM_Sandbox` (`Systems/Mover/`) reçoit `BP_VisualOverride_MetaHuman` dans `VisualOverrides_Soft`.
|
||||||
|
- **`GM_Dev` est reparenté sur `GM_Sandbox`.** C'était un `GameModeBase` totalement vide (aucune variable, aucun nœud) qui ne servait qu'à fixer `DefaultPawnClass` ; or `AC_VisualOverrideManager::FindAndApplyVisualOverride` fait un `Cast To GM_Sandbox` — sans ce reparentage, la DevMap n'appliquait **jamais** d'override (pire : le cast raté le remettait activement à zéro). `DefaultPawnClass`, `PawnClasses_Soft` et `VisualOverrides_Soft` sont renseignés sur `GM_Dev`.
|
||||||
|
- La sélection se fait par le CVar **`DDCvar.VisualOverride`** (index dans la liste, `-1` = pas d'override). Son défaut est passé de `-1` à **`0`** dans `Config/DefaultEngine.ini` pour que le MetaHuman soit affiché d'entrée. Repasser à `-1` (ou taper `DDCvar.VisualOverride -1` en console) rend le mannequin.
|
||||||
|
|
||||||
|
Vérifié en PIE : le mannequin passe invisible, `BP_VisualOverride_MetaHuman` est spawné dans le `ChildActorComponent`, le MetaHuman (corps + tête + matériaux) suit l'animation à l'arrêt comme en course, le Motion Matching continue de tourner normalement sur le mannequin caché (`PSD_Relaxed_Stand_Idles` → `PSD_Relaxed_Stand_Run_F_Loops`).
|
||||||
|
|
||||||
|
⚠️ **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 (`Maps/DevTest/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)
|
### 4.3 Autres systèmes de gameplay (ajouts spécifiques au projet)
|
||||||
|
|
||||||
```text
|
```text
|
||||||
@@ -425,21 +556,21 @@ Content/Systems/
|
|||||||
│ └── BP_Projectile_Arrow.uasset → Hérite de BP_Projectile_Base. Override du mesh `ArrowMesh` (mesh Fab `cc0_wooden_arrow`, collision `BlockAllDynamic`) via override de composant hérité (PAS le template du parent — voir piège §9). Override `HandleImpact` : au lieu de se détruire, se fige (désactive la simulation + la collision) et s'attache (KeepWorld) au composant touché pour rester planté visuellement dans le décor/la cible.
|
│ └── BP_Projectile_Arrow.uasset → Hérite de BP_Projectile_Base. Override du mesh `ArrowMesh` (mesh Fab `cc0_wooden_arrow`, collision `BlockAllDynamic`) via override de composant hérité (PAS le template du parent — voir piège §9). Override `HandleImpact` : au lieu de se détruire, se fige (désactive la simulation + la collision) et s'attache (KeepWorld) au composant touché pour rester planté visuellement dans le décor/la cible.
|
||||||
│
|
│
|
||||||
├── Wildlife/ (2026-09-05) → Premiers animaux sauvages (cerf mâle + biche). Architecture générique : toute la logique commune vit dans `BP_AnimalBase` + un unique StateTree partagé ; une espèce (Content/Systems/Wildlife/BP_Deer_Stag, BP_Deer_Doe) ne fait qu'assigner mesh/anims/tunables — ajouter un sanglier ou un loup plus tard consiste à créer UN NOUVEAU Character enfant de `BP_AnimalBase`, sans toucher au StateTree ni aux tâches. Réutilise tel quel `AC_Stats` (vie/dégâts/mort) et `BP_ScentPoint` (odeurs) — voir §1.3. Nécessite le plugin **GameplayStateTree** (ajouté à `ProjectFv1.uproject` cette session, `StateTreeAIComponentSchema`/`StateTreeComponentSchema` indisponibles sans lui — seul le plugin `StateTree` de base était actif auparavant) ; premier usage de StateTree dans ce projet (aucune Behavior Tree/Blackboard/AIController n'existait avant).
|
├── Wildlife/ (2026-09-05) → Premiers animaux sauvages (cerf mâle + biche). Architecture générique : toute la logique commune vit dans `BP_AnimalBase` + un unique StateTree partagé ; une espèce (Content/Systems/Wildlife/BP_Deer_Stag, BP_Deer_Doe) ne fait qu'assigner mesh/anims/tunables — ajouter un sanglier ou un loup plus tard consiste à créer UN NOUVEAU Character enfant de `BP_AnimalBase`, sans toucher au StateTree ni aux tâches. Réutilise tel quel `AC_Stats` (vie/dégâts/mort) et `BP_ScentPoint` (odeurs) — voir §1.3. Nécessite le plugin **GameplayStateTree** (ajouté à `ProjectFv1.uproject` cette session, `StateTreeAIComponentSchema`/`StateTreeComponentSchema` indisponibles sans lui — seul le plugin `StateTree` de base était actif auparavant) ; premier usage de StateTree dans ce projet (aucune Behavior Tree/Blackboard/AIController n'existait avant).
|
||||||
│ ├── E_AnimalState.uasset → Enum (UserDefinedEnum, créé via `unreal.EnumStructService`) : Idle/Wander/Graze/Rest/Alert/Flee/Dead. Sert d'étiquette de debug + de sélecteur d'anim (voir `BP_AnimalBase::PlayStateAnimation`) ; le StateTree stocke en interne l'état courant sous forme de `byte` (les outils Blueprint disponibles ne permettent pas d'ajouter une variable membre ou un paramètre de fonction/dispatcher directement typé sur un enum utilisateur — limitation déjà documentée §9 pour AC_Stats, confirmée à nouveau ici).
|
│ ├── E_AnimalState.uasset → Enum (UserDefinedEnum, créé via `unreal.EnumStructService`) : Idle/Wander/Graze/Rest/Alert/Flee/Dead. Sert d'étiquette de debug + de sélecteur d'anim d'arrêt (voir `BP_AnimalBase::ApplyIdleForState`) ; le StateTree stocke en interne l'état courant sous forme de `byte` (les outils Blueprint disponibles ne permettent pas d'ajouter une variable membre ou un paramètre de fonction/dispatcher directement typé sur un enum utilisateur — limitation déjà documentée §9 pour AC_Stats, confirmée à nouveau ici).
|
||||||
│ ├── AC_AnimalSenses.uasset → ActorComponent générique (vue + odorat), ajouté à `BP_AnimalBase`. Vue : ne fait AUCUNE détection elle-même — se contente de variables (`bCanSeePlayer`, `DistanceToPlayer`, `LastKnownPlayerLocation`) mises à jour par `BP_AnimalAIController` via `ReportPlayerSighted`/`ReportPlayerLostSight`. Odorat : self-contained, `CheckScent` tourne sur un timer (`ScentCheckInterval`, 0.5s par défaut) démarré au `BeginPlay`, interroge `GetAllActorsOfClass(BP_ScentPoint)` et retient le plus proche (`bScentDetected`/`ScentSourceLocation` si distance ≤ `ScentDetectionRadius`, 800 par défaut). `DistanceToPlayer` est recalculée à CHAQUE tick de `CheckScent` (pas seulement quand le joueur est vu) — nécessaire pour que le StateTree puisse détecter le retour au calme (`DistanceToPlayer >= SafeDistance`) même après que l'animal ait fui hors de vue (bug rencontré et corrigé en test PIE, voir §9).
|
│ ├── AC_AnimalSenses.uasset → ActorComponent générique (vue + odorat), ajouté à `BP_AnimalBase`. Vue : ne fait AUCUNE détection elle-même — se contente de variables (`bCanSeePlayer`, `DistanceToPlayer`, `LastKnownPlayerLocation`) mises à jour par `BP_AnimalAIController` via `ReportPlayerSighted`/`ReportPlayerLostSight`. Odorat : self-contained, `CheckScent` tourne sur un timer (`ScentCheckInterval`, 0.5s par défaut) démarré au `BeginPlay`, interroge `GetAllActorsOfClass(BP_ScentPoint)` et retient le plus proche (`bScentDetected`/`ScentSourceLocation` si distance ≤ `ScentDetectionRadius`, 800 par défaut). `DistanceToPlayer` est recalculée à CHAQUE tick de `CheckScent` (pas seulement quand le joueur est vu) — nécessaire pour que le StateTree puisse détecter le retour au calme (`DistanceToPlayer >= SafeDistance`) même après que l'animal ait fui hors de vue (bug rencontré et corrigé en test PIE, voir §9). (2026-09-14) `CheckScent` réécrit : distance calculée par point d'odeur dans la boucle (l'ancienne version comparait une valeur hors boucle), pawn joueur relu à chaque passe via `GetPlayerPawn(0)` (le cache du `BeginPlay` devenait invalide après mort/respawn → fuite infinie), `LastKnownPlayerLocation` rafraîchie tant que le joueur est vu (la perception ne notifie qu'au gain/perte de vue), et `bCanSeePlayer=false` si aucun pawn.
|
||||||
│ ├── BP_AnimalAIController.uasset → AIController, `AIPerceptionComponent` natif configuré en Python (`AISenseConfig_Sight`, rayon 2500/3000, FOV 90°). `OnTargetPerceptionUpdated` relaie vers `AC_AnimalSenses` du pion possédé (`ReportPlayerSighted`/`ReportPlayerLostSight` selon `Stimulus.WasSuccessfullySensed()`) — ne fonctionne QUE parce que le joueur porte un `AIPerceptionStimuliSourceComponent` (voir §1.3).
|
│ ├── BP_AnimalAIController.uasset → AIController, `AIPerceptionComponent` natif configuré en Python (`AISenseConfig_Sight`, rayon 2500/3000, FOV 90°). `OnTargetPerceptionUpdated` relaie vers `AC_AnimalSenses` du pion possédé (`ReportPlayerSighted`/`ReportPlayerLostSight` selon `Stimulus.WasSuccessfullySensed()`) — ne fonctionne QUE parce que le joueur porte un `AIPerceptionStimuliSourceComponent` (voir §1.3). (2026-09-14) Filtre ajouté : l'événement ne relaie QUE si `Actor == GetPlayerPawn(0)` — sans lui, les autres animaux (pawns) perçus faisaient passer `bCanSeePlayer` à vrai/faux et déclenchaient alertes/fuites entre cerfs. (2026-09-14) Le template `AIPerception` avait perdu son `AISenseConfig_Sight` (`SensesConfig = [None]` → aucune détection) : recréé par Python (`unreal.new_object(AISenseConfig_Sight, outer=<template AIPerception_GEN_VARIABLE>)` via `SubobjectDataSubsystem`), rayon 2500/3000, angle périphérique 90°, MaxAge 5, toutes affiliations. Le pawn joueur actuel (`SandboxCharacter_Mover`, pawn par défaut de `GM_Dev`) n'a pas de `AIPerceptionStimuliSourceComponent` mais est détecté via `AISense_Sight.bAutoRegisterAllPawnsAsSources` (vrai par défaut) ; en revanche il n'émet PAS d'odeurs (`ScentFunct` n'existe que sur `SandboxCharacter_CMC`).
|
||||||
│ ├── BP_AnimalBase.uasset → Character générique, base de TOUTE la faune. Composants : `Stats` (AC_Stats), `AnimalSenses` (AC_AnimalSenses), `StateTree` (StateTreeComponent, schema `StateTreeComponentSchema`, contexte = l'acteur lui-même — PAS `StateTreeAIComponentSchema`, pour rester détaché de l'AIController et garder le StateTree simple). `AIControllerClass` = `BP_AnimalAIController`, `AutoPossessAI` = Placed in World or Spawned. Tunables instance-editable : WalkSpeed/RunSpeed, WanderRadius, IdleTime/GrazeTime/RestTime(Min/Max), AlertTime, FleeDistance (400-600 : distance de panique immédiate si vu de près), SafeDistance (doit être largement > FleeDistance : distance à atteindre pour se recalmer), HerdID (Name — animaux partageant le même HerdID se relaient une alerte), DebugEnabled, Anim_Idle/Wander/Graze/Rest/Alert/Flee/Dead/Hit (AnimSequence, un jeu à fournir par espèce). Fonctions clés : `MoveTo`/`StopMovementAnimal` (wrappers autour de l'AIController caché, utilisés par les tâches StateTree), `SetCurrentState` (met à jour l'enum de debug ET déclenche `PlayStateAnimation` — lecture d'anim en **Single Node** via `SkeletalMeshComponent::PlayAnimation`, PAS d'AnimBlueprint/State Machine : suffisant pour un premier jet crédible sans blending, cf. §9), `GetThreatLocation` (position du joueur si vu, sinon source d'odeur, sinon position de l'animal), `BroadcastAlertToHerd`/`ReceiveHerdAlert` (alerte les autres membres du même HerdID sans jamais lire une variable d'une AUTRE instance directement — le HerdID appelant est passé en paramètre de fonction, voir piège §9), `HandleDeath` (ragdoll `SetAllBodiesSimulatePhysics`, lié à `AC_Stats::OnDeath` via un Custom Event `OnAnimalDeathEvt` — PAS un binding direct sur une fonction classique, voir piège §9), `CheckHealthChanged` (polling toutes les 0.2s de `AC_Stats::GetHealth` : une baisse de vie hors mort → `bWasHitRecently=true` ; préféré à un binding direct sur le dispatcher `AC_Stats::OnDamaged`, qui provoque une erreur interne du compilateur Blueprint dans ce projet, voir piège §9).
|
│ ├── BP_AnimalBase.uasset → Character générique, base de TOUTE la faune. Composants : `Stats` (AC_Stats), `AnimalSenses` (AC_AnimalSenses), `StateTree` (StateTreeComponent, schema `StateTreeComponentSchema`, contexte = l'acteur lui-même — PAS `StateTreeAIComponentSchema`, pour rester détaché de l'AIController et garder le StateTree simple). `AIControllerClass` = `BP_AnimalAIController`, `AutoPossessAI` = Placed in World or Spawned. Tunables instance-editable : WalkSpeed/RunSpeed, WanderRadius, IdleTime/GrazeTime/RestTime(Min/Max), AlertTime, FleeDistance (400-600 : distance de panique immédiate si vu de près), SafeDistance (doit être largement > FleeDistance : distance à atteindre pour se recalmer), HerdID (Name — animaux partageant le même HerdID se relaient une alerte), DebugEnabled, Anim_Idle/Wander/Graze/Rest/Alert/Flee/Dead/Hit + Anim_RestEnter/Anim_RestExit (AnimSequence, un jeu à fournir par espèce ; RestEnter/Exit optionnelles). Mouvement (2026-09-14) : `bOrientRotationToMovement=true`, `bUseControllerRotationYaw=false`, RotationRate 220, accélération sur les chemins (`NavMovementProperties.bUseAccelerationForPaths`) ; mesh tourné de Yaw −90 (les squelettes DeerStag/DeerDoe regardent +Y). Fonctions clés : `MoveTo`/`StopMovementAnimal` (wrappers autour de l'AIController caché, utilisés par les tâches StateTree), `SetCurrentState` (met à jour l'état, `bIsFleeing` (=Flee), `bInDeadState` (=Dead) et consomme `bHerdAlertReceived` à l'entrée d'Alert/Flee — ne joue plus d'anim), animation (2026-09-14) : toujours **Single Node** (`SkeletalMeshComponent::PlayAnimation`, pas d'AnimBlueprint) mais pilotée par la VITESSE à chaque tick via `DebugTick→UpdateAnimation` : course (`Anim_Flee`, play rate = vitesse/RunSpeed) au-delà de (Walk+Run)/2, marche (`Anim_Wander`, play rate = vitesse/WalkSpeed) au-delà de ~30, sinon `UpdateIdleAnimation` (Rest avec transitions RestEnter/RestExit verrouillées par `AnimLockUntil`, sinon `ApplyIdleForState` : Graze/Alert/Idle). `ApplyAnim(Anim, Loop, Rate)` ne relance l'anim QUE si elle change (`CurrentAnim`) — l'ancienne version relançait l'anim à chaque changement d'état. `PlayStateAnimation` n'est plus appelée (conservée, inutilisée), `GetThreatLocation` (position du joueur si vu, sinon source d'odeur, sinon position du pawn joueur, sinon position de l'animal), `BroadcastAlertToHerd`/`ReceiveHerdAlert` (alerte les autres membres du même HerdID sans jamais lire une variable d'une AUTRE instance directement — le HerdID appelant est passé en paramètre de fonction, voir piège §9), `HandleDeath` (2026-09-14 : plus de ragdoll — `DisableMovement`, arrêt du polling de vie, capsule en `NoCollision`, `Anim_Dead` joué une fois et figé sur sa dernière frame ; lié à `AC_Stats::OnDeath` via un Custom Event `OnAnimalDeathEvt` — PAS un binding direct sur une fonction classique, voir piège §9), `CheckHealthChanged` (polling toutes les 0.2s de `AC_Stats::GetHealth` : une baisse de vie hors mort → `HandleDamaged` : `bWasHitRecently=true`, remis à false par le timer `ClearHitFlag` 6s après le dernier coup (auparavant JAMAIS remis à false → fuite relancée à chaque tick), anim `Anim_Hit` verrouillée 0.4s ; préféré à un binding direct sur le dispatcher `AC_Stats::OnDamaged`, qui provoque une erreur interne du compilateur Blueprint dans ce projet, voir piège §9).
|
||||||
│ ├── ST_AnimalBase.uasset → StateTree partagé par toute la faune (schema `StateTreeComponentSchema`, contexte = `BP_AnimalBase`). États : `Normal` (groupe) {Idle→Wander→Graze→Rest→Idle, cycle via transitions `OnStateCompleted`/`NextState`}, `Alert` (hésite `AlertTime` secondes puis retourne à Idle si la menace n'est pas confirmée — deny-timeout), `Flee` (fuite), `Dead` (terminal). Transitions clés, TOUTES en conditions liées par binding direct au contexte (`bind_transition_condition_property_to_context`, propriétés imbriquées type `AnimalSenses.bCanSeePlayer` — inclure le préfixe `b` des booléens, voir piège §9), aucune n'exige de Blueprint condition custom : `Normal→Alert` (vue OU odorat OU alerte de horde, combinées en OR via `set_transition_condition_operand`), `Normal→Flee` et `Alert→Flee` (priorité High : vu ET distance ≤ FleeDistance — "trop près, panique immédiate"), `Flee→Normal/Idle` (distance ≥ SafeDistance ET plus vu), transitions globales posées sur `Root` (s'appliquent depuis N'IMPORTE quel état actif) : `→Flee` (priorité High, `bWasHitRecently` ET pas mort — coup reçu non-létal) et `→Dead` (priorité Critical, `bIsDead`).
|
│ ├── ST_AnimalBase.uasset → StateTree partagé par toute la faune (schema `StateTreeComponentSchema`, contexte = `BP_AnimalBase`). États : `Normal` (groupe) {Idle→Wander→Graze→Rest→Idle, cycle via transitions `OnStateCompleted`/`NextState`}, `Alert` (hésite `AlertTime` secondes puis retourne à Idle si la menace n'est pas confirmée — deny-timeout), `Flee` (fuite), `Dead` (terminal). Transitions clés, TOUTES en conditions liées par binding direct au contexte (`bind_transition_condition_property_to_context`, propriétés imbriquées type `AnimalSenses.bCanSeePlayer` — inclure le préfixe `b` des booléens, voir piège §9), aucune n'exige de Blueprint condition custom : `Normal→Alert` (vue OU odorat OU alerte de horde, combinées en OR via `set_transition_condition_operand`), `Normal→Flee` et `Alert→Flee` (priorité High : vu ET distance ≤ FleeDistance — "trop près, panique immédiate"), `Flee→Normal/Idle` (distance ≥ SafeDistance ET plus vu ET `bWasHitRecently` faux — fuite minimale de 6s après un coup, même tiré de loin), transitions globales posées sur `Root` (s'appliquent depuis N'IMPORTE quel état actif) : `→Flee` (priorité High, `bWasHitRecently` ET pas mort ET `bIsFleeing` faux — sans cette dernière condition, la transition ré-entrait dans Flee à chaque tick) et `→Dead` (priorité Critical, `bIsDead` ET `bInDeadState` faux — même raison que `bIsFleeing` : sans elle, Dead était ré-entré à chaque tick).
|
||||||
│ └── Tasks/ → StateTree Tasks en Blueprint (parent natif `StateTreeTaskBlueprintBase`), chacune réutilisée par PLUSIEURS états via ses propriétés instance-editable liées au contexte (`bind_task_property_to_context`) :
|
│ └── Tasks/ → StateTree Tasks en Blueprint (parent natif `StateTreeTaskBlueprintBase`), chacune réutilisée par PLUSIEURS états via ses propriétés instance-editable liées au contexte (`bind_task_property_to_context`) :
|
||||||
│ ├── STT_SetAnimalState.uasset → Appelle `BP_AnimalBase::SetCurrentState(NewState)` puis termine immédiatement (`FinishTask`). Un exemplaire par état-feuille, seul `NewState` diffère.
|
│ ├── STT_SetAnimalState.uasset → Appelle `BP_AnimalBase::SetCurrentState(NewState)` et ne se termine JAMAIS (2026-09-14 : l'ancien `FinishTask` immédiat, avec `TasksCompletion=Any`, terminait chaque état dans la frame même de son entrée → Idle→Wander→Graze→Rest bouclaient à chaque frame, animaux immobiles et anims relancées en permanence ; `set_task_considered_for_completion(false)` n'a PAS suffi, voir §9). C'est la tâche Wait/Move de l'état qui le termine. Un exemplaire par état-feuille, seul `NewState` diffère.
|
||||||
│ ├── STT_Wait.uasset → Attend une durée aléatoire entre `MinTime`/`MaxTime` (liés au contexte : IdleTimeMin/Max, GrazeTimeMin/Max, RestTimeMin/Max, ou AlertTime/AlertTime pour une durée fixe). Nécessite `should_call_tick_only_on_events = true` sur la classe (sinon `ReceiveLatentTick` n'est jamais appelé — propriété peu intuitive, voir piège §9).
|
│ ├── STT_Wait.uasset → Attend une durée aléatoire entre `MinTime`/`MaxTime` (liés au contexte : IdleTimeMin/Max, GrazeTimeMin/Max, RestTimeMin/Max, ou AlertTime/AlertTime pour une durée fixe). Nécessite `should_call_tick_only_on_events = true` sur la classe (sinon `ReceiveLatentTick` n'est jamais appelé — propriété peu intuitive, voir piège §9).
|
||||||
│ ├── STT_MoveToRandomPoint.uasset → Utilisé par `Wander`. Tire un point via `NavigationSystem::GetRandomReachablePointInRadius` autour de `HomeLocation` (capturée une fois au spawn), appelle `BP_AnimalBase::MoveTo`, termine en arrivant (ou après 30s de timeout de sécurité).
|
│ ├── STT_MoveToRandomPoint.uasset → Utilisé par `Wander`. Tire un point via `NavigationSystem::GetRandomReachablePointInRadius` autour de `HomeLocation` (capturée une fois au spawn), appelle `BP_AnimalBase::MoveTo`, termine en arrivant (≤120 en XY), si l'animal est bloqué (vitesse < 5 après 1.5s) ou après 25s ; `ExitState` arrête le mouvement (une alerte interrompt proprement la marche).
|
||||||
│ └── STT_MoveAwayFromThreat.uasset → Utilisé par `Flee`. À l'entrée : diffuse l'alerte à la horde puis calcule un point de fuite (direction opposée à `GetThreatLocation`, projeté sur le NavMesh, distance ≈ SafeDistance×1.3). Se ré-émet automatiquement un nouveau point de fuite si l'animal arrive à destination mais reste encore trop proche.
|
│ └── STT_MoveAwayFromThreat.uasset → Utilisé par `Flee`. À l'entrée : diffuse l'alerte à la horde puis `IssueFleeMove` : point à 1500 dans la direction opposée à `GetThreatLocation` (XY), projeté sur le NavMesh (extent 300/300/1000), sinon point atteignable aléatoire dans 1500 autour de l'animal. Ré-émis tant que l'état Flee est actif dès que l'animal arrive (≤200) ou est bloqué (vitesse < 20 après 1s) — c'est la transition du StateTree qui termine la fuite. `ExitState` arrête le mouvement.
|
||||||
│
|
│
|
||||||
│ Espèces (enfants de BP_AnimalBase, aucun nouvel asset graphique créé — réutilisent les meshes/anims
|
│ Espèces (enfants de BP_AnimalBase, aucun nouvel asset graphique créé — réutilisent les meshes/anims
|
||||||
│ déjà présents sous Content/Characters/Animal/DeerStagAndDoe/ et Content/Animations/DeerAndDoe/) :
|
│ déjà présents sous Content/Characters/Animal/DeerStagAndDoe/ et Content/Assets/Animations/DeerAndDoe/) :
|
||||||
│ ├── BP_Deer_Stag.uasset → SK_DeerStag + jeu d'anims ANIM_DeerStag_*, HerdID "DeerHerd_A".
|
│ ├── BP_Deer_Stag.uasset → SK_DeerStag + jeu d'anims ANIM_DeerStag_* (RestEnter/Exit = GoToRest/RestToGoBackUp), HerdID "DeerHerd_A".
|
||||||
│ └── BP_Deer_Doe.uasset → SK_DeerDoe + jeu d'anims ANIM_DeerDoe_*, HerdID "DeerHerd_A" (même horde que le cerf → réactivité croisée via BroadcastAlertToHerd/ReceiveHerdAlert).
|
│ └── BP_Deer_Doe.uasset → SK_DeerDoe + jeu d'anims ANIM_DeerDoe_* (`Anim_Rest`=IdleRest, manquante avant le 2026-09-14), HerdID "DeerHerd_A" (même horde que le cerf → réactivité croisée via BroadcastAlertToHerd/ReceiveHerdAlert).
|
||||||
│
|
│
|
||||||
│ Une instance de chaque a été placée dans `Content/Maps/DevMap/MapDev1` avec un `NavMeshBoundsVolume`
|
│ Une instance de chaque a été placée dans `Content/Maps/DevMap/MapDev1` avec un `NavMeshBoundsVolume`
|
||||||
│ (`NavMeshBounds_Wildlife`, RuntimeGeneration = Dynamic — le mode par défaut `Static` ne (re)génère
|
│ (`NavMeshBounds_Wildlife`, RuntimeGeneration = Dynamic — le mode par défaut `Static` ne (re)génère
|
||||||
@@ -452,7 +583,24 @@ Content/Systems/
|
|||||||
│
|
│
|
||||||
├── Movement/
|
├── Movement/
|
||||||
│ ├── Climbing/AC_ClimbingComponent.uasset, CR_ClimbingGraphV2.uasset (Control Rig), CR_Mannequin_BasicFootIK.uasset, ClimbingMaterial.uasset
|
│ ├── 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)
|
│ ├── 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 du plugin AST_StateManager, **réduite le 2026-10-30 aux ~220 assets réellement utilisés** (249 assets non référencés supprimés : caméras AST, poses/anims d'armes et de mêlée, loot, `AST_GameInstance`, maps de démo `ShowcaseMap`/`DefaultLevel1`). Gardés malgré l'absence de référence : les 2 tables de tags (déclarées en config) et `Maps/LevelPrototyping/Meshes/SM_Cube` (cible d'un `[CoreRedirects]`). Les notifies `ReloadNotify` et `SetEquippedWeapon` (utilisés par les montages d'armes AST) appelaient l'inventaire AST non porté : leur graphe est vidé (ne font rien), sinon ils ne compilaient pas.
|
||||||
|
│ │ ├── 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 → table de tags `AST.*` (déclarée dans DefaultGameplayTags.ini ; `AST_StateTreeGameplayTagDT` n'était qu'un redirecteur vers elle, supprimé avec sa ligne de config le 2026-10-30).
|
||||||
|
│ │ └── 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 déplacée dans `Content/Maps/DevTest/` le 2026-10-30, voir §7)
|
||||||
│
|
│
|
||||||
├── 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.
|
├── 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
|
├── Movable_Object/BP_Moveble_Object.uasset → Objet physique déplaçable par le joueur
|
||||||
@@ -460,7 +608,10 @@ Content/Systems/
|
|||||||
│
|
│
|
||||||
└── Weather/
|
└── Weather/
|
||||||
├── Tornado/BP_Tornado.uasset, NS_Tornado.uasset → Tornade dynamique (acteur + système Niagara), spécifique au projet (`NS_Tornado.uasset`, supprimé du disque avant le 2026-09-13 sans commit, restauré depuis git le 2026-09-14 à la demande de l'utilisateur)
|
├── Tornado/BP_Tornado.uasset, NS_Tornado.uasset → Tornade dynamique (acteur + système Niagara), spécifique au projet (`NS_Tornado.uasset`, supprimé du disque avant le 2026-09-13 sans commit, restauré depuis git le 2026-09-14 à la demande de l'utilisateur)
|
||||||
└── UltraDynamicSky/ → 🧩 **Asset marketplace tiers complet** (~789 fichiers : Blueprints, matériaux, sons, textures de ciel/météo dynamique). Ne pas modifier directement ; utiliser ses points d'extension documentés par le plugin (Weather_Presets, Climate_Presets, Sky_Modifiers). Structure interne : Blueprints/ (Enum, Functions, Occlusion, Sky_Modifiers, Sound, System, Tools, Utilities, Weather_Effects, Widgets), Materials/, Meshes/, Particles/, Sound/, Textures/, Maps/ (map de démo du plugin).
|
└── UltraDynamicSky/ → 🧩 **Asset marketplace tiers complet** (~789 fichiers : Blueprints, matériaux, sons, textures de ciel/météo dynamique). Ne pas modifier directement ; utiliser ses points d'extension documentés par le plugin (Weather_Presets, Climate_Presets, Sky_Modifiers). Structure interne : Blueprints/ (Enum, Functions, Occlusion, Sky_Modifiers, Sound, System, Tools, Utilities, Weather_Effects, Widgets), Materials/, Meshes/, Particles/, Sound/, Textures/, Maps/ (map de démo du plugin). Les systèmes Niagara `Particles/` (Snow, Dust, Wind_Debris, Radial_Storm, Puddle_FluidGrid, DLWE_Interaction_System, VolumetricCloud_LightRays, Actor_Exposure_Test, Standalone/Dripping_*) référençaient encore l'ancien chemin `/Game/UltraDynamicSky/Particles/UDW_Niagara_Parameters` / `UDS_VolumetricClouds_Niagara_Properties` : `[CoreRedirects]` ajouté dans `Config/DefaultEngine.ini` + re-sauvegarde des 10 systèmes (2026-09-14).
|
||||||
|
⚠️ **Exception — code météo PROPRE AU PROJET rangé dans ce dossier tiers** (à ne pas confondre avec le plugin) :
|
||||||
|
├── Blueprints/WB_WeatherControl.uasset → Acteur contrôleur météo (1 par map, porte UDS/UDW en ChildActor). Tick via `BP_TickManager` : fait avancer la saison (`DT_Season`, durée en minutes via `SeasonDurationScale`=60), puis si le joueur est dans une zone (`ActiveZone`) pousse la météo de cette zone vers UDW, sinon `GetNearZone` choisit les 2 zones les plus proches (poids inversement proportionnels à la distance) et `setWeatherbetweenZone` mélange leurs états dans UDW.
|
||||||
|
└── Blueprints/WB_WeatherZone.uasset → Zone météo (Box). `WeatherData` (ST_Weather_ZoneData : temp/humidité/vent/sable) = climat de base. `MakeForcast` génère 16 prévisions (`ST_Weather_Zone_forecasts`, pas de 60–240 s via `ForecastStepMin/Max`) avec `makestate` (nuages `SetNuage`, température `MakeTemp` tirée vers la moyenne de saison, neige/pluie/orage/vent/brouillard/poussière) ; `StepForecast(Delta)` interpole l'état courant et régénère en fin de séquence ; `ApplyToUDW` pousse l'état dans UDW ; `GetInflueZone` liste les zones voisines dans `InfluenceRadius` (15000 uu) non masquées (lissage entre zones via `GetZoneState`). Overlap filtré sur le pawn contrôlé par un joueur. Fonction `Trie zone` restée dans le BP mais plus appelée (2026-09-14).
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -484,7 +635,7 @@ Content/Data/
|
|||||||
├── DataAssets/
|
├── DataAssets/
|
||||||
│ ├── AttachmentData/ → AttachmentData (base) + AttachmentData_AdvancedRifle, AttachmentData_Flashlight : configuration des attachements d'armes
|
│ ├── AttachmentData/ → AttachmentData (base) + AttachmentData_AdvancedRifle, AttachmentData_Flashlight : configuration des attachements d'armes
|
||||||
│ ├── ContainerGroupData/ → Un DataAsset par "groupe de containers" (Backpack BIG/SMALL, Box/Chest Storage, Vest_1/2, ExampleStorage…) : définit la mise en page des slots d'un contenant
|
│ ├── ContainerGroupData/ → Un DataAsset par "groupe de containers" (Backpack BIG/SMALL, Box/Chest Storage, Vest_1/2, ExampleStorage…) : définit la mise en page des slots d'un contenant
|
||||||
│ └── InventoryData/ → Un DataAsset par inventaire prédéfini (PlayerInventoryPart1/2, CardReader_Inventory, Generator_Inventory, Vehicle_Inventory)
|
│ └── InventoryData/ → Un DataAsset par inventaire prédéfini (PlayerInventory, PlayerInventoryPart1/2, CardReader_Inventory, Generator_Inventory, Vehicle_Inventory). `PlayerInventory` (2026-09-16) = inventaire du JOUEUR : widget `WB_InventoryPlayer`, containers = les 12 de PlayerInventoryPart1 puis les 3 de PlayerInventoryPart2 (même ordre que `WB_InventoryPlayer::GetAllContainerWidgets`) ; le container 12 (poches) est en 4×3 / 12 slots depuis le 2026-09-17 pour correspondre à `PocketContainer` (il était en 2×2 → seule la 1re ligne était utilisable ; `PlayerInventoryPart2`, utilisé par le pillage, a toujours ce défaut). `PlayerInventoryPart1/2` restent utilisés par les PNJ/cadavres fouillables (`BP_Deadman`, `BP_EnemyPuppet` → `WB_LootingHuman`)
|
||||||
├── Enumerations/ → Enums spécifiques AGIS : EAnimOverlayState, EBallDirections, EFourDirections/ETwoDirections, EInteractionType, EItemActions, ENestingRules, EPrintType, EReloadType, EServerVerificationType, ESlotAppearance, EVendorBuyOption
|
├── Enumerations/ → Enums spécifiques AGIS : EAnimOverlayState, EBallDirections, EFourDirections/ETwoDirections, EInteractionType, EItemActions, ENestingRules, EPrintType, EReloadType, EServerVerificationType, ESlotAppearance, EVendorBuyOption
|
||||||
└── Structures/ → Structs spécifiques AGIS
|
└── Structures/ → Structs spécifiques AGIS
|
||||||
├── ItemDefaults.uasset → Struct CENTRALE décrivant un item (Name, etc.) — lue par WB_Item et par la logique de sélection rapide (Inventory_Player)
|
├── ItemDefaults.uasset → Struct CENTRALE décrivant un item (Name, etc.) — lue par WB_Item et par la logique de sélection rapide (Inventory_Player)
|
||||||
@@ -505,15 +656,16 @@ Content/UI/
|
|||||||
├── Inventory_UI/ → TOUTE l'UI de l'inventaire (socle AGIS + ajouts projet)
|
├── Inventory_UI/ → TOUTE l'UI de l'inventaire (socle AGIS + ajouts projet)
|
||||||
│ ├── MaterialResources/ → Matériaux/Material Instances de fond des slots (MI_Background_*, M_RuntimeItemMaterial…)
|
│ ├── MaterialResources/ → Matériaux/Material Instances de fond des slots (MI_Background_*, M_RuntimeItemMaterial…)
|
||||||
│ └── Widgets/
|
│ └── Widgets/
|
||||||
│ ├── WB_Container.uasset → Widget représentant un container (grille de slots) — contient SlotWidgets[]
|
│ ├── WB_Container.uasset → Widget représentant un container (grille de slots) — contient SlotWidgets[]. `CreateSlots` construit la grille d'après la `Container Size` DU WIDGET (les SlotInfo du DataAsset doivent avoir la même taille, sinon seules les premières cases sont utilisables). `GetParentEquipSlot` (corrigé le 2026-09-17) ne renvoie l'EquipSlot englobant (Outer.Outer) que si ce container EST son `Container` principal : les sous-containers d'un sac/gilet affichés ailleurs (sous les poches) gardent leur taille et leurs cases de 75 px au lieu d'être réduits à 1×1 en taille d'EquipSlot
|
||||||
│ ├── WB_EquipSlot.uasset → Widget d'un slot d'équipement (arme/speed) — contient Container. Var `OwnContainersHost` (2026-09-04) : si définie (WB_InventoryPart2), `OnContainerUpdate` ajoute les sous-containers de l'item équipé (ex. grille du sac à dos) dans ce widget via `AddContainerBelowPockets` au lieu de son propre `ContainersCanvas` interne. Câblée uniquement pour `EquipSlotBACKPACK` par `WB_InventoryScreen::InitializeWidgets`.
|
│ ├── WB_EquipSlot.uasset → Widget d'un slot d'équipement (arme/speed) — contient Container. Var `OwnContainersHost` (2026-09-04, typée `WB_InventoryPlayer` depuis 2026-09-16) : si définie, `OnContainerUpdate` ajoute les sous-containers de l'item équipé (ex. grille du sac à dos) dans ce widget via `AddContainerBelowPockets` au lieu de son propre `ContainersCanvas` interne. Câblée uniquement pour `EquipSlotBACKPACK` par `WB_InventoryScreen::InitializeWidgets`.
|
||||||
│ ├── WB_InventorySlot.uasset → Widget d'un slot individuel dans une grille — expose "ItemWidget On Slot"
|
│ ├── WB_InventorySlot.uasset → Widget d'un slot individuel dans une grille — expose "ItemWidget On Slot"
|
||||||
│ ├── WB_Item.uasset → Widget représentant un item posé dans un slot — expose "Item Defaults" (struct ItemDefaults)
|
│ ├── WB_Item.uasset → Widget représentant un item posé dans un slot — expose "Item Defaults" (struct ItemDefaults)
|
||||||
│ │
|
│ │
|
||||||
│ ├── InventoryMenu/
|
│ ├── InventoryMenu/
|
||||||
│ │ ├── WB_InventoryScreen.uasset → Widget racine de l'inventaire plein écran (contient InventoryPart1/InventoryPart2)
|
│ │ ├── WB_InventoryScreen.uasset → Widget racine de l'inventaire plein écran. Depuis 2026-09-16 contient un seul panneau joueur `Part2Box → OutlinePart2 → BackgroundPart2 → InventoryPlayer` (WB_InventoryPlayer : équipements à gauche, poches + sac à dos défilants à droite ; plus de ScrollBox extérieur depuis 2026-09-17, sinon la colonne de droite n'a pas de hauteur bornée) ; `InitializeWidgets` initialise `InventoryPlayer` et câble `EquipSlotBACKPACK.OwnContainersHost = InventoryPlayer`. `Inventory_Player::GetQuickSlotItemInfo` lit les slots WEAPON/WEAPON2/Speed1/Speed2 via `InventoryScreen.InventoryPlayer`. **Overlay personnage (2026-09-21)** : `Border_184` (→ `Overlay_261` : portrait `Image_163`, textes h/hunger, `WB_stat_player_Body`) est replié (`Collapsed`) dès qu'un inventaire tiers est ouvert (corps, coffre, feu de camp…) : `CreateLootingWidget` appelle `HideCharacterOverlay` après avoir affiché `LootWindow` ; `ShowCharacterOverlay` (appelé après `AddToViewport` dans `ToggleScreen` et dans `Clear Looting Widget Panel`) le remet `Visible` seulement si `LootWindow` n'est pas visible (une fermeture sans fondu laisse le panneau de loot en place — comportement d'origine)
|
||||||
│ │ ├── WB_InventoryPart1.uasset → Contient les 4 slots d'équipement (EquipSlotWEAPON, EquipSlotWEAPON2, EquipSlotSpeed1, EquipSlotSpeed2) + autres slots d'équipement (casque, gilet, gants, sac à dos…)
|
│ │ ├── WB_InventoryPlayer.uasset → (2026-09-16) Fusion de WB_InventoryPart1 + WB_InventoryPart2 pour l'inventaire du joueur, dans un seul cadre en deux colonnes (2026-09-17) : `EquipsVertical` → `ColumnsBox` (HorizontalBox, Fill) → [`EquipSlotsBox` (SizeBox 760×866) → `SlotsCanvas` avec les 12 EquipSlots] + [`PocketsScroll` (ScrollBox, barre visible) → `VerticalBox_0` (titre Pockets + `PocketContainer`, puis les containers du sac à dos ajoutés dessous par `Add Container Below Pockets`)]. `EquipSlotBACKPACK` et `EquipSlotVEST` ont `Item Containers Settings.ShowInventory = True` et `OwnContainersHost = InventoryPlayer` (câblé dans `WB_InventoryScreen::InitializeWidgets`) (défaut de WB_EquipSlot = False : sans ça, `OnContainerUpdate` ne crée jamais les grilles du sac). `GetAllEquipSlots` = même ordre que Part1 ; `GetAllContainerWidgets` = containers des équipements puis PocketContainer. Données : DataAsset `PlayerInventory`
|
||||||
│ │ └── WB_InventoryPart2.uasset → Grille(s) d'inventaire principale(s) (PocketContainer + titre, dans `VerticalBox_0`). Fonction `Add Container Below Pockets(Container)` (2026-09-04) : insère un WB_Container juste après le bloc Pockets (`PocketContainer.GetParent().GetParent()`) — utilisée par `WB_EquipSlot` (sac à dos) pour afficher ses slots supplémentaires sous les slots Pocket plutôt que dans son propre canvas.
|
│ │ ├── WB_InventoryPart1.uasset → (utilisé seulement par WB_LootingHuman depuis 2026-09-16) Contient les 4 slots d'équipement (EquipSlotWEAPON, EquipSlotWEAPON2, EquipSlotSpeed1, EquipSlotSpeed2) + autres slots d'équipement (casque, gilet, gants, sac à dos…)
|
||||||
|
│ │ └── WB_InventoryPart2.uasset → (utilisé seulement par WB_LootingHuman depuis 2026-09-16 ; sa fonction `Add Container Below Pockets` n'est plus appelée, WB_EquipSlot pointe désormais WB_InventoryPlayer) Grille(s) d'inventaire principale(s) (PocketContainer + titre, dans `VerticalBox_0`). Fonction `Add Container Below Pockets(Container)` (2026-09-04) : insère un WB_Container juste après le bloc Pockets (`PocketContainer.GetParent().GetParent()`) — utilisée par `WB_EquipSlot` (sac à dos) pour afficher ses slots supplémentaires sous les slots Pocket plutôt que dans son propre canvas.
|
||||||
│ │
|
│ │
|
||||||
│ ├── ItemActionsMenu/WB_ItemMenu.uasset, WB_GeneralButton.uasset → Menu contextuel d'actions sur un item
|
│ ├── ItemActionsMenu/WB_ItemMenu.uasset, WB_GeneralButton.uasset → Menu contextuel d'actions sur un item
|
||||||
│ │
|
│ │
|
||||||
@@ -540,7 +692,7 @@ Content/UI/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. `Content/Items/`, `Content/PCG/`, `Content/Maps/`, `Content/VFX/`, `Content/Prop/`
|
## 7. `Content/Items/`, `Content/PCG/`, `Content/Maps/`, `Content/VFX/`
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Content/Items/ → Objets ramassables/équipables du jeu
|
Content/Items/ → Objets ramassables/équipables du jeu
|
||||||
@@ -548,15 +700,17 @@ Content/Items/ → Objets ramassables/équipables du
|
|||||||
│ ├── _BP_ItemBase.uasset → Blueprint BASE de tout item (racine de hiérarchie). Event `Custom|UpdateCollisionandPhysics` (appelé à l'attache/au drop) bascule aussi la réponse au canal `Visibility` (Ignore quand équipé / Block quand lâché) du mesh principal ET de tous les `WidgetComponent` de l'item (ex. `AmmoUI`) — fix du 2026-09-04 : un item équipé bloquait les BoxTrace (canal Visibility) du système de grimpe/parkour (`AC_ClimbingComponent`), empêchant de grimper une fois une arme en main.
|
│ ├── _BP_ItemBase.uasset → Blueprint BASE de tout item (racine de hiérarchie). Event `Custom|UpdateCollisionandPhysics` (appelé à l'attache/au drop) bascule aussi la réponse au canal `Visibility` (Ignore quand équipé / Block quand lâché) du mesh principal ET de tous les `WidgetComponent` de l'item (ex. `AmmoUI`) — fix du 2026-09-04 : un item équipé bloquait les BoxTrace (canal Visibility) du système de grimpe/parkour (`AC_ClimbingComponent`), empêchant de grimper une fois une arme en main.
|
||||||
│ ├── BP_Item_HoldableBase.uasset → Base des items tenables en main. Implémente `BPI_HoldableItem::On Item Attached(ShouldHold)` (seul signal fiable du VRAI état main/pas-en-main) et diffuse ce booléen via son propre dispatcher `OnHeldStateChanged(bIsHeld)` (2026-09) — c'est CE dispatcher (et non `_BP_ItemBase::OnOwnerChanged`, qui se déclenche aussi pour un simple rangement en inventaire) qu'`AC_Weapon` écoute pour piloter Equip/Unequip, voir §4.3.
|
│ ├── BP_Item_HoldableBase.uasset → Base des items tenables en main. Implémente `BPI_HoldableItem::On Item Attached(ShouldHold)` (seul signal fiable du VRAI état main/pas-en-main) et diffuse ce booléen via son propre dispatcher `OnHeldStateChanged(bIsHeld)` (2026-09) — c'est CE dispatcher (et non `_BP_ItemBase::OnOwnerChanged`, qui se déclenche aussi pour un simple rangement en inventaire) qu'`AC_Weapon` écoute pour piloter Equip/Unequip, voir §4.3.
|
||||||
│ ├── BP_Item_Armor_Base.uasset → Base des items d'armure/équipement porté
|
│ ├── BP_Item_Armor_Base.uasset → Base des items d'armure/équipement porté
|
||||||
│ └── BP_Item_Skeletal_Base.uasset → Base des items avec mesh squelettal
|
│ ├── BP_Item_Skeletal_Base.uasset → Base des items avec mesh squelettal
|
||||||
|
│ └── BP_Item_OutfitPiece_Base.uasset → (2026-09-21) Base des vêtements MetaHuman équipables (hérite `BP_Item_Armor_Base`). `ItemMesh_STATIC` (tag ItemMeshAGIS = mesh au sol) + `OutfitCloth` (ChaosClothComponent, asset `OA_SurvivorOutfit`, caché par défaut). BeginPlay → `SetupOutfitBinding` (ignoré pour les acteurs de prévisualisation d'icône) : s'abonne à `OnOwnerChanged` → `RefreshOutfit`, puis `ApplyVisibleSlots`. `RefreshOutfit` : avec propriétaire, attache `OutfitCloth` au mesh enfant du ChildActorComponent tagué `VisualOverride` (le `Body` du MetaHuman ; à défaut le 1er SkeletalMeshComponent du pion) + `SetLeaderPoseComponent`, montre le cloth, cache le mesh statique ; sans propriétaire, l'inverse. `ApplyVisibleSlots` : si `VisibleMaterialSlots` (Name[]) n'est pas vide, remplace le matériau de chaque autre slot par `M_OutfitPieceHidden` → une pièce = même tenue complète dont on n'affiche que ses matériaux. Coût : chaque pièce équipée simule la tenue entière (3 simulations cloth si les 3 sont portées). ⚠️ Tenue taillée pour le corps `Bof2` : la peau du MetaHuman `test` traverse le pantalon aux cuisses (correctif propre = garde-robe du MetaHuman Creator).
|
||||||
│
|
│
|
||||||
├── BP_Item_AdvancedRifle / _Backpack_Camper / _Backpack_Sport / _BodyArmor / _Flashlight /
|
├── BP_Item_AdvancedRifle / _Backpack_Camper / _Backpack_Sport / _BodyArmor / _Flashlight /
|
||||||
│ _Gloves / _Helmet / _KevlarVest / _LightVest / _Siren / _Bow.uasset → Blueprints d'items "portés" (racine d'Items/). `BP_Item_Bow` (hérite `BP_Item_HoldableBase`) porte un composant `ItemMesh_STATIC` (mesh Fab `survival_kit_bow_fixed` — voir §8 pour l'incident de corruption/ré-import du 2026-09-05 —, socket `ArrowSocket` ajouté pour l'encoche — position approximative, à ajuster visuellement), équipé sur le socket `weapon_l` (Spine `SpineRifle`, réutilisé faute de socket dédié). `BP_Item_AdvancedRifle` a reçu le même composant `AC_Weapon` (2026-09-05, retrofit de validation) pour l'équipement/déséquipement générique ; sa cadence de tir reste pilotée par sa propre macro interne `Weapon|FiringGate` (non branchée sur `AC_Weapon.CanUse()` — dette technique documentée, voir §9).
|
│ _Gloves / _Helmet / _KevlarVest / _LightVest / _Siren / _Bow.uasset → Blueprints d'items "portés" (racine d'Items/). `BP_Item_Bow` (hérite `BP_Item_HoldableBase`) porte un composant `ItemMesh_STATIC` (mesh Fab `survival_kit_bow_fixed` — voir §8 pour l'incident de corruption/ré-import du 2026-09-05 —, socket `ArrowSocket` ajouté pour l'encoche — position approximative, à ajuster visuellement), équipé sur le socket `weapon_l` (Spine `SpineRifle`, réutilisé faute de socket dédié). `BP_Item_AdvancedRifle` a reçu le même composant `AC_Weapon` (2026-09-05, retrofit de validation) pour l'équipement/déséquipement générique ; sa cadence de tir reste pilotée par sa propre macro interne `Weapon|FiringGate` (non branchée sur `AC_Weapon.CanUse()` — dette technique documentée, voir §9).
|
||||||
│
|
│
|
||||||
│ **Gameplay de l'arc** (`BP_Item_Bow`, 2026-09-05/06) — override des hooks existants `Custom|PrimaryUse`/`StopPrimaryUsing` de `_BP_ItemBase`, sans nouveau système d'input : `PrimaryUse` vérifie `AC_Weapon->CanUse()` ET `CountArrows() >= 1` (fonction propre, voir §1.3 pour `Owner Inventory`) avant de démarrer la tension (horodatage `DrawStartTime`, pas de Timeline), puis joue `Draw Montage` (`AM_Bow_Draw`, voir ci-dessous) sur le mesh du personnage. `StopPrimaryUsing` calcule la puissance (`Clamp((Now-DrawStartTime)/MaxDrawTime, MinDrawPower, 1.0)`), joue `Fire Montage` (`AM_Bow_Fire`), appelle `ConsumeArrow()` et, si réussi, spawn `BP_Projectile_Arrow` au socket `ArrowSocket` avec vitesse/dégâts scalés par la puissance, puis appelle `AC_Weapon->TryUsePrimary()`.
|
│ **Gameplay de l'arc** (`BP_Item_Bow`, 2026-09-05/06) — override des hooks existants `Custom|PrimaryUse`/`StopPrimaryUsing` de `_BP_ItemBase`, sans nouveau système d'input : `PrimaryUse` vérifie `AC_Weapon->CanUse()` ET `CountArrows() >= 1` (fonction propre, voir §1.3 pour `Owner Inventory`) avant de démarrer la tension (horodatage `DrawStartTime`, pas de Timeline), puis joue `Draw Montage` (`AM_Bow_Draw`, voir ci-dessous) sur le mesh du personnage. `StopPrimaryUsing` calcule la puissance (`Clamp((Now-DrawStartTime)/MaxDrawTime, MinDrawPower, 1.0)`), joue `Fire Montage` (`AM_Bow_Fire`), appelle `ConsumeArrow()` et, si réussi, spawn `BP_Projectile_Arrow` au socket `ArrowSocket` avec vitesse/dégâts scalés par la puissance, puis appelle `AC_Weapon->TryUsePrimary()`.
|
||||||
│ **`ConsumeArrow()` — fix du 2026-09-06** : retrouve le stack "Arrow" via `BOTH|FindItem`, puis réduit son montant via `Inventory__Main::AddItemAmount(ItemAddress, -1)` — une opération purement sur les DONNÉES de l'inventaire, par adresse, ne nécessitant aucun acteur monde. L'implémentation d'origine appelait `Utilities|GetItemActor` (macro `ML_InventoryMacros::Get Item Actor`) puis `SERVER|ReduceAmount` sur cet acteur — ce qui échoue TOUJOURS silencieusement pour un item empilé passif comme "Arrow" qui, tant qu'il n'est pas équipé/lâché dans le monde, n'a jamais d'acteur spawné (`GetItemActor` retourne systématiquement invalide). Symptôme observé : le tir semblait démarrer (logs "TIR EN COURS") mais aucune flèche ne partait et aucune munition n'était consommée. Voir aussi §9 pour la même leçon appliquée à toute consommation de stock passif (ne jamais utiliser `GetItemActor`+fonction-sur-acteur pour un item qui n'est pas garanti d'être spawné dans le monde — utiliser `Inventory__Main::AddItemAmount` par adresse à la place).
|
│ **`ConsumeArrow()` — fix du 2026-09-06** : retrouve le stack "Arrow" via `BOTH|FindItem`, puis réduit son montant via `Inventory__Main::AddItemAmount(ItemAddress, -1)` — une opération purement sur les DONNÉES de l'inventaire, par adresse, ne nécessitant aucun acteur monde. L'implémentation d'origine appelait `Utilities|GetItemActor` (macro `ML_InventoryMacros::Get Item Actor`) puis `SERVER|ReduceAmount` sur cet acteur — ce qui échoue TOUJOURS silencieusement pour un item empilé passif comme "Arrow" qui, tant qu'il n'est pas équipé/lâché dans le monde, n'a jamais d'acteur spawné (`GetItemActor` retourne systématiquement invalide). Symptôme observé : le tir semblait démarrer (logs "TIR EN COURS") mais aucune flèche ne partait et aucune munition n'était consommée. Voir aussi §9 pour la même leçon appliquée à toute consommation de stock passif (ne jamais utiliser `GetItemActor`+fonction-sur-acteur pour un item qui n'est pas garanti d'être spawné dans le monde — utiliser `Inventory__Main::AddItemAmount` par adresse à la place).
|
||||||
│ **Animations de l'arc** (2026-09-06) — `AM_Bow_Draw`/`AM_Bow_Fire.uasset` (`Content/Items/`) sont des `AnimMontage` à piste unique générés depuis `standingdrawarrow_UE`/`standingaimrecoil_UE` (`Content/Animations/humain/Armed_mov/Bow/`), assignés au **slot `UpperBody`** (voir `SandboxCharacter_CMC_ABP` ci-dessous — PAS `DefaultSlot`). Variables `Draw Montage`/`Fire Montage` sur `BP_Item_Bow`, jouées via un nœud natif `Animation|Montage|PlayMontage` sur le mesh du personnage (`Cast Owner Character → Character → GetMesh`). Appel direct (pas de variante Multicast `...CLIENTS` comme pour `PlayReloadMontageCLIENTS` du fusil) — suffisant en PIE solo ; à revoir si une réplication multijoueur de l'anim est nécessaire plus tard.
|
│ **Animations de l'arc** (2026-09-06) — `AM_Bow_Draw`/`AM_Bow_Fire.uasset` (`Content/Items/`) sont des `AnimMontage` à piste unique générés depuis `standingdrawarrow_UE`/`standingaimrecoil_UE` (`Content/Assets/Animations/humain/Armed_mov/Bow/`), assignés au **slot `UpperBody`** (voir `SandboxCharacter_CMC_ABP` ci-dessous — PAS `DefaultSlot`). Variables `Draw Montage`/`Fire Montage` sur `BP_Item_Bow`, jouées via un nœud natif `Animation|Montage|PlayMontage` sur le mesh du personnage (`Cast Owner Character → Character → GetMesh`). Appel direct (pas de variante Multicast `...CLIENTS` comme pour `PlayReloadMontageCLIENTS` du fusil) — suffisant en PIE solo ; à revoir si une réplication multijoueur de l'anim est nécessaire plus tard.
|
||||||
│ **Intégration à la locomotion (2026-09-06)** — un montage plein-corps sur `DefaultSlot` remplaçait TOUT le squelette (jambes comprises) par la pose figée de l'animation source, ce qui semblait correct à l'arrêt (la pose "debout" du montage coïncide avec Motion Matching à l'arrêt) mais cassait la marche/course/crouch (jambes figées dans la pose d'arc "debout" enregistrée). Fix : ajout d'un **`Slot 'UpperBody'`** + nœud **`Layered Blend Per Bone`** dans l'`AnimGraph` de `SandboxCharacter_CMC_ABP`, avec un filtre de branche sur l'os `spine_01` (BlendDepth=-1 → toute la branche colonne+bras+tête, jambes/bassin exclus) — voir §9 pour le détail technique (le skeleton `SK_UEFN_Mannequin` avait déjà un Blend Profile "UpperBody" masquant exactement les mêmes os, confirmant que `spine_01` est le bon point de coupure, mais ce Blend Profile n'est pas directement utilisable par ce nœud en 5.8 — filtre de branche manuel utilisé à la place). Le `DefaultSlot` existant (plein corps) n'est pas touché, réutilisable tel quel pour de futures actions plein-corps. Motion Matching, Pose Search, Aim Offset (`Enable_AO`/`Get_AOValue`), Foot/Leg IK et Orientation Warping — tous déjà présents dans cet AnimBP — continuent de piloter le bas du corps et la visée sans changement.
|
│ **Intégration à la locomotion (2026-09-06)** — un montage plein-corps sur `DefaultSlot` remplaçait TOUT le squelette (jambes comprises) par la pose figée de l'animation source, ce qui semblait correct à l'arrêt (la pose "debout" du montage coïncide avec Motion Matching à l'arrêt) mais cassait la marche/course/crouch (jambes figées dans la pose d'arc "debout" enregistrée). Fix : ajout d'un **`Slot 'UpperBody'`** + nœud **`Layered Blend Per Bone`** dans l'`AnimGraph` de `SandboxCharacter_CMC_ABP`, avec un filtre de branche sur l'os `spine_01` (BlendDepth=-1 → toute la branche colonne+bras+tête, jambes/bassin exclus) — voir §9 pour le détail technique (le skeleton `SK_UEFN_Mannequin` avait déjà un Blend Profile "UpperBody" masquant exactement les mêmes os, confirmant que `spine_01` est le bon point de coupure, mais ce Blend Profile n'est pas directement utilisable par ce nœud en 5.8 — filtre de branche manuel utilisé à la place). Le `DefaultSlot` existant (plein corps) n'est pas touché, réutilisable tel quel pour de futures actions plein-corps. Motion Matching, Pose Search, Aim Offset (`Enable_AO`/`Get_AOValue`), Foot/Leg IK et Orientation Warping — tous déjà présents dans cet AnimBP — continuent de piloter le bas du corps et la visée sans changement.
|
||||||
|
├── BP_Item_SurvivorOutfit_Top / _Pants / _Boots.uasset → (2026-09-21) Les 3 pièces de la tenue MetaHuman « SurvivorOutfit », enfants de `BP_Item_OutfitPiece_Base`. Lignes DT_Items `SurvivorOutfit_Top` (`Human.Body` → EquipSlotBODY, partagé avec BodyArmor), `SurvivorOutfit_Pants` (`Human.Pant` → EquipSlotPANTS), `SurvivorOutfit_Boots` (`Human.Shoes` → EquipSlotSHOES) ; icônes générées au runtime. Chaque enfant ne fixe que `VisibleMaterialSlots` (Top = MI_Survivor_Coat + MI_Survivor_Tshirt, Pants = MI_Survivor_Pant, Boots = MI_Survivor_Boot) et l'override du mesh au sol `ItemMesh_STATIC` (SM_SurvivorOutfit_Coat/Pant/Boot). `BP_Spawner5` de MapDev1 pointe sur `SurvivorOutfit_Top`.
|
||||||
├── Attachments/BP_Item_MagazineBase, BP_Item_RifleFlashlight, BP_Item_Suppressor.uasset → Attachements d'armes
|
├── Attachments/BP_Item_MagazineBase, BP_Item_RifleFlashlight, BP_Item_Suppressor.uasset → Attachements d'armes
|
||||||
├── ItemObjects/BPI_MergeableItemObject, ItemObject__BASE, ItemObject_ConsumableBASE, ItemObject_Magazine.uasset → Objets "monde" associés aux items (empilables, consommables, munitions)
|
├── ItemObjects/BPI_MergeableItemObject, ItemObject__BASE, ItemObject_ConsumableBASE, ItemObject_Magazine.uasset → Objets "monde" associés aux items (empilables, consommables, munitions)
|
||||||
│
|
│
|
||||||
@@ -566,32 +720,78 @@ Content/Items/ → Objets ramassables/équipables du
|
|||||||
│
|
│
|
||||||
├── Resources/ → Assets 3D (mesh/matériau/texture) groupés par équipement porté, + cas particuliers
|
├── Resources/ → Assets 3D (mesh/matériau/texture) groupés par équipement porté, + cas particuliers
|
||||||
│ ├── Backpack_Camper/, Backpack_Sport/, BodyArmor/, Gloves/, Helmet/, KevlarVest/, LightVest/, Rifle/
|
│ ├── Backpack_Camper/, Backpack_Sport/, BodyArmor/, Gloves/, Helmet/, KevlarVest/, LightVest/, Rifle/
|
||||||
|
│ ├── Outfits/M_OutfitPieceHidden.uasset → (2026-09-21) Matériau masqué à opacité 0, utilisé par `BP_Item_OutfitPiece_Base` pour cacher les pièces d'une tenue qui n'appartiennent pas à l'item
|
||||||
│ ├── _Others/ → Assets des petits objets (Keycard, Log, Meat, AmmoBox, Battery, Flashlight, FuelCanister, GoldIngot/GoldOre, Headphone, MoneyBag, WaterBottle)
|
│ ├── _Others/ → Assets des petits objets (Keycard, Log, Meat, AmmoBox, Battery, Flashlight, FuelCanister, GoldIngot/GoldOre, Headphone, MoneyBag, WaterBottle)
|
||||||
│ └── ABP_SkeletalEquippables.uasset → Anim Blueprint partagé par les items squelettaux équipés
|
│ └── ABP_SkeletalEquippables.uasset → Anim Blueprint partagé par les items squelettaux équipés
|
||||||
│
|
│
|
||||||
└── ItemTextures/ → Textures d'icônes/inventaire communes à tous les items (T_*)
|
└── ItemTextures/ → Textures d'icônes/inventaire communes à tous les items (T_*)
|
||||||
|
|
||||||
Content/PCG/ → Génération procédurale de contenu (plugin PCG)
|
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)
|
||||||
|
│ └── (niveau de test : `Maps/DevTest/L_PF_HaussmannTest`)
|
||||||
|
├── 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)
|
||||||
|
│ └── (niveau de test : `Maps/DevTest/L_PF_RoadBridgeTest`)
|
||||||
|
├── 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)
|
│ ├── 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
|
│ ├── 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
|
│ ├── M_Road.uasset, ST_Road_data.uasset, EM_Road_Type.uasset → Matériau, struct de données et enum de types de route
|
||||||
├── Vegetation/TreeTest.uasset → Graphe PCG de placement de végétation (arbres, générés via PVE pour la route)
|
└── Vegetation/TreeTest.uasset → Graphe PCG de placement de végétation (arbres, générés via PVE pour la route)
|
||||||
└── test/NewPCGGraph1.uasset → Graphe de test/brouillon
|
|
||||||
|
|
||||||
Content/Maps/DevMap/
|
Content/Maps/
|
||||||
├── MapDev1.umap → 🗺️ Map de développement PRINCIPALE (GameDefaultMap / EditorStartupMap, voir Config/DefaultEngine.ini)
|
├── DevMap/ → Map de développement principale et rien d'autre
|
||||||
├── GM_Dev.uasset → GameMode utilisé sur MapDev1 (hérite directement de GameModeBase, indépendant de GM_Sandbox/Gamemode_AGIS)
|
│ ├── MapDev1.umap → 🗺️ Map de développement PRINCIPALE (GameDefaultMap / EditorStartupMap, voir Config/DefaultEngine.ini)
|
||||||
├── pcg_Test_Dev.umap → Map de test PCG
|
│ ├── GM_Dev.uasset → GameMode utilisé sur MapDev1 (enfant de GM_Sandbox, §4.2.4)
|
||||||
└── PCG_Test_Dev_HLODLayer_*, Untitled_HLOD0_Instancing.uasset → Assets HLOD générés pour les maps de test
|
│ └── _GENERATED/ → Meshes fusionnés générés par l'éditeur, placés dans MapDev1
|
||||||
|
└── DevTest/ → (2026-10-30) TOUTES les maps de test, rangées à plat (règle : une nouvelle map de test va ici,
|
||||||
|
│ jamais dans le dossier du système testé)
|
||||||
|
├── L_ASTCoverTest.umap → Couverture + interactions AST (murs bas/haut + CoverWallActor, portes, placard, levier, caisse ; GM_Dev)
|
||||||
|
├── L_MoverTest.umap + GM_MoverTest → Ancien banc d'essai du personnage Mover (GameMode propre à cette map)
|
||||||
|
├── L_BridgeTest.umap, L_BridgeTest_Geo.umap → Kits de ponts (Assets/Environment/Bridges) ; _Geo charge les ponts entiers (très lourds en mémoire)
|
||||||
|
├── L_KitFR_Demo.umap → Présentation du kit KitFR
|
||||||
|
├── L_PF_Demo.umap → Présentation des assets ProjectF + variantes (acteurs tagués PF_VARIANTES)
|
||||||
|
├── L_RueDeParis.umap → Rue de test (RueDeParis + PropsParis + KitFR)
|
||||||
|
├── L_PF_HaussmannTest.umap → PCG Haussmann : 8 variantes (H0 à H4, R+4 à R+7, FacadeLength, îlot fermé, angle), non partitionnée
|
||||||
|
├── L_PF_RoadBridgeTest.umap → PCG routes et ponts : 9 scénarios, World Partition (terrain 1 km², rivière, ruisseau, vallée)
|
||||||
|
├── pcg_Test_Dev.umap → Ancienne map de test PCG (World Partition)
|
||||||
|
└── HLOD/ → Couches HLOD générées des deux maps World Partition
|
||||||
|
|
||||||
Content/VFX/
|
Content/VFX/
|
||||||
├── Firetrail/BP_FireTrail.uasset, Effects/P_BulletTrail.uasset, Materials/M_BulletTrail.uasset → Traînée de balle
|
├── Firetrail/BP_FireTrail.uasset, Effects/P_BulletTrail.uasset, Materials/M_BulletTrail.uasset → Traînée de balle
|
||||||
└── MI_MuzzleFlash, M_MuzzleFlash, MuzzleFlash, P_MuzzleFlash → Effet de tir (bouche de canon)
|
└── MI_MuzzleFlash, M_MuzzleFlash, MuzzleFlash, P_MuzzleFlash → Effet de tir (bouche de canon)
|
||||||
├── M_Blood.uasset, T_Blood.uasset → Effet de sang
|
├── M_Blood.uasset, T_Blood.uasset → Effet de sang
|
||||||
└── crosshair.uasset, hitmarker.uasset → Éléments de HUD de tir
|
└── crosshair.uasset, hitmarker.uasset → Éléments de HUD de tir
|
||||||
|
|
||||||
Content/Prop/Wooden_Door/ → Prop de porte en bois (mesh + matériaux), utilisé par les BP de porte interactable
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -600,16 +800,32 @@ Content/Prop/Wooden_Door/ → Prop de porte en bois (mesh + mat
|
|||||||
|
|
||||||
Ces dossiers contiennent des assets achetés/importés (Marketplace, Fab/Quixel Megascans, Megaplant, packs d'animation mocap). Ils sont volumineux (des centaines de fichiers) et **ne sont volontairement pas détaillés fichier par fichier** ici — voir §10 pour la règle sur quand les documenter.
|
Ces dossiers contiennent des assets achetés/importés (Marketplace, Fab/Quixel Megascans, Megaplant, packs d'animation mocap). Ils sont volumineux (des centaines de fichiers) et **ne sont volontairement pas détaillés fichier par fichier** ici — voir §10 pour la règle sur quand les documenter.
|
||||||
|
|
||||||
|
**Règle de rangement (2026-10-30)** : les packs d'art faits pour le projet (générés dans Blender, importés par les scripts de `ProjetF blender/`) vont sous `Content/Assets/Environment/<Pack>/`, les bibliothèques d'animation sous `Content/Assets/Animations/`. Les imports dont le chemin est imposé par l'outil (Fab, Megaplant_Library, MetaHumans) restent où l'outil les met. **Exception assumée** : `KitFR/` et `ProjectF/` sont restés à la racine de `Content/` (2 000 et 1 600 assets ; les déplacer dans l'éditeur le fait planter par manque de mémoire, décision utilisateur du 2026-10-30).
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Content/Animations/ → Clips de mocap tiers : DeerAndDoe/, Fox/, Wolf/, humain/ (Armed_mov, Avoid, Carrying, Cover,
|
Content/Assets/Animations/ → Clips de mocap tiers : DeerAndDoe/, Fox/, Wolf/, humain/ (Armed_mov, Avoid, Carrying, Cover,
|
||||||
Effect_Animation, INteraction, Prone, Push, SwimmingAnimation…)
|
Effect_Animation, INteraction, Prone, Push, SwimmingAnimation…). Ex-`Content/Animations/` (déplacé le 2026-10-30).
|
||||||
|
Kimodo/ : animations générées par le skill kimodo-motion (Source/ = import du GLB skinné + IK_Kimodo_SOMA30
|
||||||
|
+ RTG_Kimodo_to_UEFN, Retargeted/ = anims retargetées sur l'UEFN Mannequin). Ex-`Content/Kimodo/`.
|
||||||
|
Content/Assets/Environment/ → Packs d'environnement faits pour le projet (déplacés ici le 2026-10-30) :
|
||||||
|
PropsParis/ (props urbains parisiens : mobilier, commerces, enseignes, débris ; meshes SM_PR_*),
|
||||||
|
RueDeParis/ (rue de test : sol, façades et décor RDP_*, script `kit_fr_scripts/ue_rdp.py`),
|
||||||
|
Bridges/ (voir ligne dédiée plus bas), Prop/Wooden_Door/ (porte en bois des BP de porte interactable).
|
||||||
Content/Characters/ → Meshes/matériaux/textures des personnages et animaux (Animal/DeerStagAndDoe|Fox|Wolf,
|
Content/Characters/ → Meshes/matériaux/textures des personnages et animaux (Animal/DeerStagAndDoe|Fox|Wolf,
|
||||||
UEFN_Mannequin/ avec ses données de Motion Matching : AimOffset, Crouch, Idle, Jump,
|
UEFN_Mannequin/ avec ses données de Motion Matching : AimOffset, Crouch, Idle, Jump,
|
||||||
MotionMatchingData/ [Channels, Databases, Normalization_Sets, Schemas], Poses, Run, Slide,
|
MotionMatchingData/ [Channels, Databases, Normalization_Sets, Schemas], Poses, Run, Slide,
|
||||||
Sprint, Traversal, Walk, Rigs, Materials, Meshes, Textures)
|
Sprint, Traversal, Walk, Rigs, Materials, Meshes, Textures)
|
||||||
|
MEtahuman/ : le MetaHuman `test` (asset MetaHuman Character `test`) et son assemblage
|
||||||
|
`Unpacked/test/` (BP_test, SKM_test_BodyMesh/FaceMesh, PHYS_test, matériaux baked), utilisé
|
||||||
|
par le visual override (§4.2.4). Ex-`Content/test/` (déplacé le 2026-10-30).
|
||||||
Content/Fab/ → Assets Fab/Quixel Megascans : MaterialFunctions/, MaterialParameterCollection/, Materials/
|
Content/Fab/ → Assets Fab/Quixel Megascans : MaterialFunctions/, MaterialParameterCollection/, Materials/
|
||||||
(Standard/VT), Megascans/Plants/ (Common_Hemp_Nettle, Wild_Grass ×2), Megascans/Surfaces/
|
(Standard/VT), Megascans/Plants/ (Common_Hemp_Nettle, Wild_Grass ×2), Megascans/Surfaces/
|
||||||
(Damaged_Asphalt, Dirt_Ground, Forest_Floor), Textures/ (Standard/VT)
|
(Damaged_Asphalt, Dirt_Ground, Forest_Floor), Textures/ (Standard/VT)
|
||||||
|
MetaHuman/ (2026-09-21) : tenue MetaHuman « SurvivorOutfit » (manteau+t-shirt+pantalon+bottes)
|
||||||
|
— `OA_SurvivorOutfit` (ChaosOutfitAsset, 4 slots de matériaux = 4 pièces, porté par `BP_Item_OutfitPiece_Base` et ses 3 enfants, §7),
|
||||||
|
`WI_OA_SurvivorOutfit` (Wardrobe Item du MetaHuman Creator), cloth assets/Dataflow,
|
||||||
|
SM_SurvivorOutfit_Coat/Pant/Boot (meshes statiques, servent d'objet au sol), textures.
|
||||||
|
Le SkeletalMesh `bodyShapeBof2_CombinedSkelMesh` est le CORPS de référence du fitting, pas la tenue.
|
||||||
Survival_Kit_-_Bow/ et CC0_-_Wooden_Arrow/ (StaticMesh + Textures + MI_SurvivalBow/MI_WoodenArrow,
|
Survival_Kit_-_Bow/ et CC0_-_Wooden_Arrow/ (StaticMesh + Textures + MI_SurvivalBow/MI_WoodenArrow,
|
||||||
utilisés par les items Bow/Arrow, voir §4.4) — ⚠️ ces deux imports glTF avaient leurs slots de
|
utilisés par les items Bow/Arrow, voir §4.4) — ⚠️ ces deux imports glTF avaient leurs slots de
|
||||||
matériau pointant vers un `MaterialInstanceDynamic` transitoire (jamais sauvegardable, cause
|
matériau pointant vers un `MaterialInstanceDynamic` transitoire (jamais sauvegardable, cause
|
||||||
@@ -629,6 +845,31 @@ 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
|
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
|
(`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).
|
`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/Assets/Environment/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). ⚠️ Déplacé le 2026-10-30 depuis
|
||||||
|
`Content/Bridges/` : en partie dans l'éditeur, et pour 81 fichiers de `Geo/` (matériaux + PCG), sur disque
|
||||||
|
éditeur fermé + `[CoreRedirects]` `/Game/Bridges/` → `/Game/Assets/Environment/Bridges/` (DefaultEngine.ini).
|
||||||
|
**Ne pas retirer cette redirection** : les ponts entiers `Geo/Full/SM_Geo_*` (90-180 Mo chacun) référencent
|
||||||
|
encore leurs matériaux par l'ancien chemin. Charger ces ponts demande ~10 Go de RAM chacun.
|
||||||
Content/Megaplant_Library/ → Végétation Megaplant : Plant_Bilberry/, Tree_European_Aspen/, Tree_Hornbeam/
|
Content/Megaplant_Library/ → Végétation Megaplant : Plant_Bilberry/, Tree_European_Aspen/, Tree_Hornbeam/
|
||||||
(chacun avec Instances/, Materials/, Textures/)
|
(chacun avec Instances/, Materials/, Textures/)
|
||||||
Content/Audio/Foley/ → **(2026-09-08)** Système de sons de pas/foley du sample Game Animation Sample :
|
Content/Audio/Foley/ → **(2026-09-08)** Système de sons de pas/foley du sample Game Animation Sample :
|
||||||
@@ -644,8 +885,10 @@ Content/Levels/, Content/Widgets/, Content/dev_map → **SUPPRIMÉS le 2026-09-
|
|||||||
LevelPrototyping, widgets et map de démo). Seul lien avec le projet : le cast vers
|
LevelPrototyping, widgets et map de démo). Seul lien avec le projet : le cast vers
|
||||||
`LevelBlock_Traversable` dans `Systems/Mover/AC_TraversalLogic`, retiré (voir §4.2.1).
|
`LevelBlock_Traversable` dans `Systems/Mover/AC_TraversalLogic`, retiré (voir §4.2.1).
|
||||||
Sauvegarde : commit git `6eb7516`.
|
Sauvegarde : commit git `6eb7516`.
|
||||||
Content/Thumbnails/ → Miniatures générées pour la Content Browser
|
Content/Misc/ → SandboxAnimCurveCompressionSettings.uasset (réglages de compression d'anim, référencés par ~1 100
|
||||||
Content/Misc/ → SandboxAnimCurveCompressionSettings.uasset (réglages de compression d'anim)
|
animations : laissé en place, le déplacer resauvegarderait toutes ces anims).
|
||||||
|
Content/Thumbnails/ → **SUPPRIMÉ le 2026-10-30** : T_aaa/T_bbbb (inutilisées) supprimées, T_SM_WaterBottle_Thumbnail
|
||||||
|
rangée dans `Items/ItemTextures/`.
|
||||||
Content/__ExternalActors__/ → ⚙️ Généré automatiquement par World Partition (données par-acteur des maps, ex. LocomotionAnimPack).
|
Content/__ExternalActors__/ → ⚙️ Généré automatiquement par World Partition (données par-acteur des maps, ex. LocomotionAnimPack).
|
||||||
Content/__ExternalObjects__/ → ⚙️ Généré automatiquement par World Partition (objets externes liés aux maps).
|
Content/__ExternalObjects__/ → ⚙️ Généré automatiquement par World Partition (objets externes liés aux maps).
|
||||||
→ Ces deux derniers dossiers ne doivent JAMAIS être édités ou documentés à la main :
|
→ Ces deux derniers dossiers ne doivent JAMAIS être édités ou documentés à la main :
|
||||||
@@ -696,6 +939,12 @@ 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 :
|
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.
|
||||||
|
- **Lire l'état de jeu en PIE depuis Python est décalé d'une frame ou deux** (surtout pour les variables d'Anim Blueprint écrites dans l'update thread-safe) : une même valeur peut sembler « fausse » (allure restée à Run, `ValidDatabases` vide) puis correcte à l'appel suivant. Toujours relire dans un second appel avant de conclure à un bug. De plus, `BlueprintService.list_graphs`/`list_variables` renvoient **0 élément pendant une session PIE** : arrêter le PIE avant d'inspecter un graphe.
|
||||||
- **`build_graph`** attend un champ **`"ref"`** pour identifier chaque nœud dans la liste `nodes` (pas `"id"`). Un mauvais nom de champ échoue silencieusement (retourne `None` sans erreur explicite).
|
- **`build_graph`** attend un champ **`"ref"`** pour identifier chaque nœud dans la liste `nodes` (pas `"id"`). Un mauvais nom de champ échoue silencieusement (retourne `None` sans erreur explicite).
|
||||||
- Les **variables locales à une fonction** (paramètres, locals créés via `add_object_variable` avec `graph=...`) ne sont pas fiables avec `build_graph`'s `variable_get`/`variable_set` : préférer des **variables membres** du Blueprint.
|
- Les **variables locales à une fonction** (paramètres, locals créés via `add_object_variable` avec `graph=...`) ne sont pas fiables avec `build_graph`'s `variable_get`/`variable_set` : préférer des **variables membres** du Blueprint.
|
||||||
- Un `K2Node_VariableSet`/`Get` créé via un spawner_key générique (`discover_nodes` + `create_node_by_key`) peut se résoudre sur la **mauvaise classe** si plusieurs Blueprints chargés ont une variable de même nom affiché (ex. "Owner Inventory" existe à la fois sur `WB_Container` et sur un widget créé cette session) — toujours vérifier les pins du nœud créé (`get_node_pins`) avant de câbler, ou utiliser `build_graph` avec `type: "variable_set"` + `params.variable` en contexte "self" qui est fiable.
|
- Un `K2Node_VariableSet`/`Get` créé via un spawner_key générique (`discover_nodes` + `create_node_by_key`) peut se résoudre sur la **mauvaise classe** si plusieurs Blueprints chargés ont une variable de même nom affiché (ex. "Owner Inventory" existe à la fois sur `WB_Container` et sur un widget créé cette session) — toujours vérifier les pins du nœud créé (`get_node_pins`) avant de câbler, ou utiliser `build_graph` avec `type: "variable_set"` + `params.variable` en contexte "self" qui est fiable.
|
||||||
@@ -724,6 +973,9 @@ Ce projet est modifié via le plugin **VibeUE** (service MCP `unreal-mcp`, voir
|
|||||||
- Une donnée cross-instance (lire la variable d'un AUTRE acteur de même classe, ex. le `HerdID` d'un autre `BP_AnimalBase` pendant `BroadcastAlertToHerd`) n'est PAS accessible via le getter `Variables|Default|GetXxx` généré par la DSL (celui-ci n'a pas de pin `self`/cible, contrairement aux nœuds `Class|MaClasse|MaFonction` qui, eux, exposent bien un `self` substituable). Solution : passer la donnée nécessaire en PARAMÈTRE de la fonction appelée sur l'autre instance plutôt que de tenter de la lire directement (voir `ReceiveHerdAlert(ThreatLocation, CallerHerdID)`).
|
- Une donnée cross-instance (lire la variable d'un AUTRE acteur de même classe, ex. le `HerdID` d'un autre `BP_AnimalBase` pendant `BroadcastAlertToHerd`) n'est PAS accessible via le getter `Variables|Default|GetXxx` généré par la DSL (celui-ci n'a pas de pin `self`/cible, contrairement aux nœuds `Class|MaClasse|MaFonction` qui, eux, exposent bien un `self` substituable). Solution : passer la donnée nécessaire en PARAMÈTRE de la fonction appelée sur l'autre instance plutôt que de tenter de la lire directement (voir `ReceiveHerdAlert(ThreatLocation, CallerHerdID)`).
|
||||||
- Une nouvelle **StateTree** (`unreal.StateTreeService.create_state_tree`) démarre SANS aucun état racine : `add_state(path, "Root", ...)` échoue silencieusement (retourne `False`) tant qu'un premier `add_state(path, "", "Root", "State")` (parent_path **vide**) n'a pas créé l'état racine lui-même.
|
- Une nouvelle **StateTree** (`unreal.StateTreeService.create_state_tree`) démarre SANS aucun état racine : `add_state(path, "Root", ...)` échoue silencieusement (retourne `False`) tant qu'un premier `add_state(path, "", "Root", "State")` (parent_path **vide**) n'a pas créé l'état racine lui-même.
|
||||||
- Lier une `AC_Stats::OnDamaged` (dispatcher avec paramètres) directement à une fonction Blueprint CLASSIQUE (pas un Custom Event) via `K2Node_CreateDelegate.set_create_delegate_function` **compile sans erreur immédiate** mais casse la compilation à la volée suivante avec `Internal compiler error inside CreateExecutionSchedule` — et peut même faire apparaître des nœuds `AddEvent` parasites (EventTick, EventActorBeginOverlap…) ailleurs dans le graphe. Un dispatcher avec paramètres doit être lié à un **Custom Event** (`add_event` avec un nom arbitraire crée un vrai `K2Node_CustomEvent`, contrairement à `write_graph_dsl`'s `(event Nom ...)` qui n'accepte que les noms d'événements natifs "AddEvent|Nom" connus). Un dispatcher SANS paramètre (ex. `AC_Stats::OnDeath`) ne pose aucun problème lié à une fonction classique.
|
- Lier une `AC_Stats::OnDamaged` (dispatcher avec paramètres) directement à une fonction Blueprint CLASSIQUE (pas un Custom Event) via `K2Node_CreateDelegate.set_create_delegate_function` **compile sans erreur immédiate** mais casse la compilation à la volée suivante avec `Internal compiler error inside CreateExecutionSchedule` — et peut même faire apparaître des nœuds `AddEvent` parasites (EventTick, EventActorBeginOverlap…) ailleurs dans le graphe. Un dispatcher avec paramètres doit être lié à un **Custom Event** (`add_event` avec un nom arbitraire crée un vrai `K2Node_CustomEvent`, contrairement à `write_graph_dsl`'s `(event Nom ...)` qui n'accepte que les noms d'événements natifs "AddEvent|Nom" connus). Un dispatcher SANS paramètre (ex. `AC_Stats::OnDeath`) ne pose aucun problème lié à une fonction classique.
|
||||||
|
- (2026-09-14) `BlueprintTools.write_graph_dsl` **échoue en silence** : en cas d'erreur (nœud inexistant, pin incompatible) il ne lève rien, retourne `None` et laisse le graphe inchangé ou VIDE ; le vrai message n'apparaît que dans `Saved/Logs/ProjectFv1.log` (`LogScript: Warning: AssertionError: The node could not be created / … does not exist` ou `RuntimeError: Could not connect pin …`). Toujours vérifier chaque écriture par `read_graph_dsl` (chercher un nœud attendu) avant de sauvegarder. Pièges constatés : (a) `Math|Byte|Equal(Byte)` et `Math|Vector|vector+vector` sont RELUS par `read_graph_dsl` mais REFUSÉS à l'écriture — utiliser les opérateurs `==`/`+` ; (b) les appels de fonction du Blueprint lui-même (`CallFunction|MaFonction`) ont une pin `self` en première position : passer les arguments par mot-clé (`:Anim x :Loop true`), sinon le premier argument est branché sur `self` ; (c) les getters de variables à underscore perdent l'underscore dans le type_id (`Anim_Idle` → `Variables|Default|GetAnimIdle`), et `find_node_types` renvoie aussi `CallFunction|ApplyIdleforState` avec la casse de l'affichage ; (d) `read_graph_dsl` affiche parfois un nœud sous une catégorie trompeuse (`CustomizableObjectInstance|SetCurrentState` pour un appel à `BP_AnimalBase::SetCurrentState`) — vérifier avec `get_node_infos` avant de conclure à un mauvais binding ; (e) `BlueprintTools.create_node` attend un `unreal.IntPoint` pour `pos`, pas un `Vector2D`.
|
||||||
|
- (2026-09-14) StateTree : une tâche Blueprint qui appelle `FinishTask` dans `EnterState` termine l'état dans la même frame (`TasksCompletion=Any`), et `StateTreeService.set_task_considered_for_completion(..., False)` renvoie `True` mais n'a PAS empêché ce comportement en PIE (UE 5.8). Pour une tâche « fire and forget » (ex. `STT_SetAnimalState`), ne PAS appeler `FinishTask`. Diagnostic : `log LogStateTree Verbose` en PIE puis compter les `Enter state` dans le log.
|
||||||
|
- (2026-09-14) StateTree : une transition posée sur `Root` (trigger `OnTick`) reste évaluée quand sa CIBLE est déjà active et la ré-entre à chaque tick (Exit/Enter de toutes ses tâches). Toute transition globale doit donc porter une condition « pas déjà dans cet état » (ex. `bIsFleeing == false` pour `Root→Flee`).
|
||||||
- Un **NavMeshBoundsVolume** ajouté par script (`SceneTools.add_to_scene_from_class`) ne génère PAS automatiquement de NavMesh : le `RecastNavMesh-Default` correspondant naît avec `RuntimeGeneration = Static` (aucune régénération, ni en éditeur ni au runtime, sans un "Build Paths" manuel — introuvable dans l'API Python exposée). Fix : `recastNavMesh.set_editor_property("runtime_generation", unreal.RuntimeGenerationType.DYNAMIC)` PUIS `unreal.NavigationSystem.on_navigation_bounds_updated(nav_sys, volume)` pour forcer une première génération immédiate (sans ce second appel, le volume reste sans tuiles jusqu'au premier changement de géométrie pertinent).
|
- Un **NavMeshBoundsVolume** ajouté par script (`SceneTools.add_to_scene_from_class`) ne génère PAS automatiquement de NavMesh : le `RecastNavMesh-Default` correspondant naît avec `RuntimeGeneration = Static` (aucune régénération, ni en éditeur ni au runtime, sans un "Build Paths" manuel — introuvable dans l'API Python exposée). Fix : `recastNavMesh.set_editor_property("runtime_generation", unreal.RuntimeGenerationType.DYNAMIC)` PUIS `unreal.NavigationSystem.on_navigation_bounds_updated(nav_sys, volume)` pour forcer une première génération immédiate (sans ce second appel, le volume reste sans tuiles jusqu'au premier changement de géométrie pertinent).
|
||||||
- **FAUX AMI corrigé (2026-09-05)** : `read_graph_dsl` insère parfois un `_` de lisibilité dans le nom affiché d'une variable membre commençant par un préfixe court en majuscule (ex. la variable réelle `LContainer` s'affiche `(|GetL_Container)`, PAS `(|GetLContainer)` — idem `LItemName`→`L_ItemName`). Utiliser cette forme AVEC underscore pour créer/écrire un nœud (`create_node`, `write_graph_dsl`) échoue avec "... does not exist", ce qui peut faire croire à tort à une variable locale non-créable (variables locales et membres se comportent en réalité de façon identique côté création). Avant toute chirurgie sur un Get/Set qui échoue ainsi, vérifier le nom SANS underscore via `find_node_types` (ex. filtrer `"LContainer"`) plutôt que de supposer une limitation de l'outil — le nom réel de la propriété (`get_editor_property` en Python inclus) ne contient jamais cet underscore ajouté par l'affichage.
|
- **FAUX AMI corrigé (2026-09-05)** : `read_graph_dsl` insère parfois un `_` de lisibilité dans le nom affiché d'une variable membre commençant par un préfixe court en majuscule (ex. la variable réelle `LContainer` s'affiche `(|GetL_Container)`, PAS `(|GetLContainer)` — idem `LItemName`→`L_ItemName`). Utiliser cette forme AVEC underscore pour créer/écrire un nœud (`create_node`, `write_graph_dsl`) échoue avec "... does not exist", ce qui peut faire croire à tort à une variable locale non-créable (variables locales et membres se comportent en réalité de façon identique côté création). Avant toute chirurgie sur un Get/Set qui échoue ainsi, vérifier le nom SANS underscore via `find_node_types` (ex. filtrer `"LContainer"`) plutôt que de supposer une limitation de l'outil — le nom réel de la propriété (`get_editor_property` en Python inclus) ne contient jamais cet underscore ajouté par l'affichage.
|
||||||
- Un Blueprint qui est la classe d'un **composant actif dans une session PIE en cours** peut compiler sans erreur mais **échouer silencieusement à la sauvegarde** (`save_loaded_asset` renvoie `False` sans exception) tant que le PIE n'est pas arrêté — toujours `StopPIE` avant de sauvegarder un asset qu'une session PIE utilise, et re-tenter la sauvegarde après l'arrêt.
|
- Un Blueprint qui est la classe d'un **composant actif dans une session PIE en cours** peut compiler sans erreur mais **échouer silencieusement à la sauvegarde** (`save_loaded_asset` renvoie `False` sans exception) tant que le PIE n'est pas arrêté — toujours `StopPIE` avant de sauvegarder un asset qu'une session PIE utilise, et re-tenter la sauvegarde après l'arrêt.
|
||||||
@@ -754,6 +1006,38 @@ 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é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.
|
- **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).
|
||||||
|
|
||||||
|
**Déplacer des assets en masse (rangement du 2026-10-30) :**
|
||||||
|
- **Map World Partition** : `AssetTools.rename_assets` ne déplace QUE les acteurs externes chargés. Les autres restent dans l'ancien dossier `__ExternalActors__`, rattachés à l'ancienne map, et disparaissent de la nouvelle. Toujours faire d'abord `WorldPartitionBlueprintLibrary.load_actors([d.guid for d in get_actor_descs()])` sur la map ouverte, puis le renommage, puis compter les fichiers `__ExternalActors__` avant/après.
|
||||||
|
- **Mémoire** : renommer un asset recharge et resauvegarde tous ses référenceurs. Déplacer un matériau des ponts entiers `Bridges/Geo/Full` (ou tout asset utilisé par de gros meshes Nanite) les recharge et les recompile (~10 Go chacun) → « Ran out of memory / fichier de pagination insuffisant ». La mémoire n'est pas rendue après un lot, même avec `collect_garbage()` : redémarrer l'éditeur tous les 2-3 gros meshes. Pour les dossiers trop lourds, déplacer sur disque éditeur fermé + `[CoreRedirects]` `MatchSubstring` (méthode utilisée pour Bridges).
|
||||||
|
- **Copies fantômes** : `rename_assets` renvoie True mais laisse parfois l'ancien fichier sur disque comme un VRAI asset (pas un redirecteur) ; c'est arrivé pour des SkeletalMesh, PhysicsAsset, DNA, textures de MetaHuman et Kimodo. Après un déplacement, chercher dans l'ancien dossier les fichiers sans `ObjectRedirector`, vérifier qu'ils ne sont référencés par rien, puis les supprimer.
|
||||||
|
- Ne jamais garder une référence Python à un monde (`w = get_editor_world()`) au moment de charger un autre niveau : assertion « World Memory Leaks » et plantage. Faire le chargement dans une fonction, sans variable globale.
|
||||||
|
- Il n'existe pas d'API Python pour « Fix Up Redirectors » : resauvegarder les référenceurs (`EditorLoadingAndSavingUtils.save_packages`), vérifier qu'il n'y en a plus, puis effacer les redirecteurs.
|
||||||
|
- `EditorAssetLibrary.delete_asset` sur une map ou un asset très référencé peut prendre plusieurs minutes (l'éditeur vérifie les références de tout le projet) ; `delete_loaded_assets` sur une liste est beaucoup plus rapide.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. Maintenir ce document à jour
|
## 10. Maintenir ce document à jour
|
||||||
@@ -787,4 +1071,13 @@ Ce document **doit toujours refléter l'état réel du projet**. Un skill dédi
|
|||||||
|
|
||||||
- *2026-09-14 (reprise) : test PIE sur `MapDev1` — `GM_Dev` fait apparaître `SandboxCharacter_CMC`, aucune erreur de Blueprint à l'exécution. Seuls messages, antérieurs : `Systems/Weather/UltraDynamicSky/Particles/Snow` référence encore l'ancien chemin `/Game/UltraDynamicSky/Particles/UDW_Niagara_Parameters`, et 4 avertissements Pose Search d'entrées vides dans `PSD_SwimmingIdle`/`PSD_SwimmingMovingSprint` (contenu inchangé depuis `d29748b`, de nouveau chargé grâce au chooser restauré). Restauration depuis `d29748b` des 7 données Motion Matching dégradées par la migration (voir §8.2) avec fix MatchAny refait, et de `NS_Tornado`. Compilation complète : 379 Blueprints, seule erreur `BP_Item_AdvancedRifle` (`Reload_Rifle_Hip` sans squelette, antérieure).*
|
- *2026-09-14 (reprise) : test PIE sur `MapDev1` — `GM_Dev` fait apparaître `SandboxCharacter_CMC`, aucune erreur de Blueprint à l'exécution. Seuls messages, antérieurs : `Systems/Weather/UltraDynamicSky/Particles/Snow` référence encore l'ancien chemin `/Game/UltraDynamicSky/Particles/UDW_Niagara_Parameters`, et 4 avertissements Pose Search d'entrées vides dans `PSD_SwimmingIdle`/`PSD_SwimmingMovingSprint` (contenu inchangé depuis `d29748b`, de nouveau chargé grâce au chooser restauré). Restauration depuis `d29748b` des 7 données Motion Matching dégradées par la migration (voir §8.2) avec fix MatchAny refait, et de `NS_Tornado`. Compilation complète : 379 Blueprints, seule erreur `BP_Item_AdvancedRifle` (`Reload_Rifle_Hip` sans squelette, antérieure).*
|
||||||
|
|
||||||
*`Content/Data/DT_DemoTags.uasset` (anciennement à la racine) : longtemps considéré comme un reste de test sans référence — FAUX (vérifié le 2026-09-13) : c'est la table de tags AGIS déclarée dans `Config/DefaultGameplayTags.ini`, à conserver (voir §2.1).*
|
- *2026-09-14 (météo) : corrections du système météo projet (`WB_WeatherControl`/`WB_WeatherZone`, voir §4 Weather). Bugs corrigés : `setWeatherbetweenZone` lisait deux fois Zone2 ; `GetNearZone` ne trouvait jamais de zone (distances locales à 0, poids 0/0 et inversés) ; `SetNuage`/`MakeTemp` retournaient 0 sans zone voisine (return dans la boucle) et clampaient la température à 0–10 ; `makestate` renvoyait un état vide (branche froide nuages ≥ 8) et ne calculait ni vent/brouillard/poussière ni humidité ; `MakeForcast` avait des pas de 0–1 s ; `UpdateWeatherstate` n'avançait jamais le temps (+0) ; rayon d'influence ≈ 900 uu et tri `Trie zone` pouvant boucler à l'infini ; overlaps déclenchés par n'importe quel acteur ; saison en secondes. Nouveaux : fonctions `StepForecast`, `ApplyToUDW`, `GetZoneState` ; variables `ForecastStepMin/Max`, `InfluenceRadius`, `LastUpdateTime` (zone), `SeasonDurationScale` (contrôleur). `[CoreRedirects]` UDS + 10 systèmes Niagara re-sauvegardés. PIE OK (zones prêtes, 16 prévisions, poids 0.52/0.48, UDW alimenté, aucune erreur météo). Restant : `WeatherData` des 2 zones de MapDev1 vide (0 °C / 0 %), `BP_TickManager` transmet un `DeltaTime` ~10× trop petit au contrôleur (saison lente), avertissement d'attache des ChildActor UDS/UDW (mobilité). Sauvegarde des assets avant modification : `E:\projet\ProjectFv1_backup_migration_2026-09-13\weather_before_fixes_2026-09-14\`.*
|
||||||
|
|
||||||
|
- *2026-09-18 (migration cover / prone / nage du CMC vers le Mover, voir §4.2.2) : `SandboxCharacter_Mover` reçoit `AC_Cover` + `Arrow1`, les variables et fonctions de cover/prone/nage, l'enregistrement du mode « Swimming » au BeginPlay, et ses fonctions `Get_Gait`/`Get_MoveInput`/`Get_PropertiesForAnimation`/`On_PreSimulateTick` étendues. Nouveaux assets : `Systems/Mover/MovementModes/BP_MovementMode_Swimming`, `Characters/UEFN_Mannequin/Animations/MotionMatchingData/CHT_PoseSearchDatabases_Mover`. Corrections annexes : `BP_MovementMode_Walking` (vitesse/accélération nulles pour les allures prone et nage), `MovementModeMap` (Ragdoll→Climbing et Flying→SwimmingOnSurface, séquelles de la fusion des enums — le ragdoll du pion refonctionne), `SandboxCharacter_Mover_ABP` (contexte `self` absent des `Evaluate Chooser` → branche Motion Matching inerte ; nouvelle bascule `AnimBranchIndex`). Testé en PIE : prone (capsule 40 ↔ 86 via le `StanceModifier`, base `PSD_Dense_Prone_Idles` sélectionnée), nage dans `WaterBodyLake_0` (entrée/flottaison à la profondeur cible/plongée/sortie, `PSD_SwimmingIdle` sélectionnée), accroupi de couverture. NON testé : entrée en couverture par la touche P et déplacement le long d'un vrai mur. Sauvegarde des assets avant modification : `E:\projet\ProjectFv1_backup_mover_migration_2026-09-17\`.*
|
||||||
|
- *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`.*
|
||||||
|
- *2026-10-30 (rangement de `Content/`) : toutes les maps de test regroupées dans `Content/Maps/DevTest/` (+ `HLOD/`) ; packs `PropsParis`, `RueDeParis`, `Bridges`, `Prop` → `Content/Assets/Environment/`, `Animations` + `Kimodo` → `Content/Assets/Animations/`, `Content/test` (MetaHuman) → `Characters/MEtahuman/Unpacked/test`. `KitFR/` et `ProjectF/` laissés à la racine (trop lourds à déplacer). Supprimés : 249 assets AST inutilisés du StateManager, maps de démo (`ShowcaseMap`, 2× `DefaultLevel1`, UltraDynamicSky `DemoMap`), `Untitled_HLOD0_Instancing`, `PCG/test/NewPCGGraph1`, `Thumbnails/T_aaa|T_bbbb`, ~280 redirecteurs, dossiers vides. `[CoreRedirects]` ajouté pour `/Game/Bridges/`. Notifies AST `ReloadNotify`/`SetEquippedWeapon` vidés. Chemins mis à jour dans les scripts `ProjetF blender/` et le skill kimodo-motion. Vérifié : 476 Blueprints compilent sans erreur, PIE MapDev1 sans erreur. Sauvegarde : `E:\projet\ProjectFv1_backup_reorg_2026-10-30\` + commit `e829ff2`. Pièges en §9.*
|
||||||
@@ -23,7 +23,7 @@ SkeletalMesh.UseExperimentalChunking=1
|
|||||||
r.Nanite.Foliage=True
|
r.Nanite.Foliage=True
|
||||||
|
|
||||||
[/Script/WindowsTargetPlatform.WindowsTargetSettings]
|
[/Script/WindowsTargetPlatform.WindowsTargetSettings]
|
||||||
DefaultGraphicsRHI=DefaultGraphicsRHI_DX11
|
DefaultGraphicsRHI=DefaultGraphicsRHI_DX12
|
||||||
-D3D12TargetedShaderFormats=PCD3D_SM5
|
-D3D12TargetedShaderFormats=PCD3D_SM5
|
||||||
+D3D12TargetedShaderFormats=PCD3D_SM6
|
+D3D12TargetedShaderFormats=PCD3D_SM6
|
||||||
-D3D11TargetedShaderFormats=PCD3D_SM5
|
-D3D11TargetedShaderFormats=PCD3D_SM5
|
||||||
@@ -116,7 +116,7 @@ ManualIPAddress=
|
|||||||
+CVarsArray=(Type=CVarInt,Name="DDCvar.FootPlacementMode",ToolTip="0 == off, 1 == foot placement node, 2 == biped control rig",DefaultValueFloat=0.000000,DefaultValueInt=1,DefaultValueBool=False)
|
+CVarsArray=(Type=CVarInt,Name="DDCvar.FootPlacementMode",ToolTip="0 == off, 1 == foot placement node, 2 == biped control rig",DefaultValueFloat=0.000000,DefaultValueInt=1,DefaultValueBool=False)
|
||||||
+CVarsArray=(Type=CVarInt,Name="DDCvar.ControlStyle",ToolTip="",DefaultValueFloat=0.000000,DefaultValueInt=0,DefaultValueBool=False)
|
+CVarsArray=(Type=CVarInt,Name="DDCvar.ControlStyle",ToolTip="",DefaultValueFloat=0.000000,DefaultValueInt=0,DefaultValueBool=False)
|
||||||
+CVarsArray=(Type=CVarInt,Name="DDCvar.PawnClass",ToolTip="",DefaultValueFloat=0.000000,DefaultValueInt=-1,DefaultValueBool=False)
|
+CVarsArray=(Type=CVarInt,Name="DDCvar.PawnClass",ToolTip="",DefaultValueFloat=0.000000,DefaultValueInt=-1,DefaultValueBool=False)
|
||||||
+CVarsArray=(Type=CVarInt,Name="DDCvar.VisualOverride",ToolTip="",DefaultValueFloat=0.000000,DefaultValueInt=-1,DefaultValueBool=False)
|
+CVarsArray=(Type=CVarInt,Name="DDCvar.VisualOverride",ToolTip="",DefaultValueFloat=0.000000,DefaultValueInt=0,DefaultValueBool=False)
|
||||||
+CVarsArray=(Type=CVarInt,Name="DDCvar.AnalogInputStyle",ToolTip="",DefaultValueFloat=0.000000,DefaultValueInt=0,DefaultValueBool=False)
|
+CVarsArray=(Type=CVarInt,Name="DDCvar.AnalogInputStyle",ToolTip="",DefaultValueFloat=0.000000,DefaultValueInt=0,DefaultValueBool=False)
|
||||||
|
|
||||||
[/Script/Engine.CollisionProfile]
|
[/Script/Engine.CollisionProfile]
|
||||||
@@ -215,3 +215,36 @@ DialogueFilenameFormat="{DialogueGuid}_{ContextId}"
|
|||||||
bEnableLegacyAssetTypes=False
|
bEnableLegacyAssetTypes=False
|
||||||
PlatformSettings=()
|
PlatformSettings=()
|
||||||
|
|
||||||
|
[CoreRedirects]
|
||||||
|
+PackageRedirects=(OldName="/Game/UltraDynamicSky/Particles/UDW_Niagara_Parameters",NewName="/Game/Systems/Weather/UltraDynamicSky/Particles/UDW_Niagara_Parameters")
|
||||||
|
+PackageRedirects=(OldName="/Game/UltraDynamicSky/Particles/UDS_VolumetricClouds_Niagara_Properties",NewName="/Game/Systems/Weather/UltraDynamicSky/Particles/UDS_VolumetricClouds_Niagara_Properties")
|
||||||
|
; Rangement 2026-10-30 : Bridges deplace sur disque (editeur ferme, trop lourd a deplacer dans l'editeur)
|
||||||
|
+PackageRedirects=(OldName="/Game/Bridges/",NewName="/Game/Assets/Environment/Bridges/",MatchSubstring=true)
|
||||||
|
; Port AST (2026-09-27) : contenu des plugins AST copie a la main dans Content/Systems/Movement
|
||||||
|
+PackageRedirects=(OldName="/AST_CoverSystem/",NewName="/Game/Systems/Movement/Cover/",MatchSubstring=true)
|
||||||
|
+PackageRedirects=(OldName="/AST_InteractionSystem/",NewName="/Game/Systems/Movement/Interaction/",MatchSubstring=true)
|
||||||
|
+PackageRedirects=(OldName="/AST_StateManager/",NewName="/Game/Systems/Movement/StateManager/",MatchSubstring=true)
|
||||||
|
; Sous-ensemble minimal (enums/interfaces/objets d'interaction) des autres plugins AST, copie dans ASTShared
|
||||||
|
+PackageRedirects=(OldName="/AST_InventorySystem/",NewName="/Game/Systems/Movement/ASTShared/Inventory/",MatchSubstring=true)
|
||||||
|
+PackageRedirects=(OldName="/AST_MeleeCombatSystem/",NewName="/Game/Systems/Movement/ASTShared/Melee/",MatchSubstring=true)
|
||||||
|
+PackageRedirects=(OldName="/AST_NPCSystem/",NewName="/Game/Systems/Movement/ASTShared/NPC/",MatchSubstring=true)
|
||||||
|
+PackageRedirects=(OldName="/AST_ParkourSystem/",NewName="/Game/Systems/Movement/ASTShared/Parkour/",MatchSubstring=true)
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/AnimModifiers/AM_MoveData_Speed",NewName="/Game/Systems/Blueprints/AnimModifiers/AM_MoveData_Speed")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/BPI_SandboxCharacter_ABP",NewName="/Game/Systems/Mover/BPI_SandboxCharacter_ABP")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/BPI_SandboxCharacter_Pawn",NewName="/Game/Systems/Mover/BPI_SandboxCharacter_Pawn")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/Data/E_Gait",NewName="/Game/Systems/Blueprints/Data/E_Gait")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/Data/E_MovementMode",NewName="/Game/Systems/Blueprints/Data/E_MovementMode")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/Data/E_Stance",NewName="/Game/Systems/Blueprints/Data/E_Stance")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/Data/S_CharacterPropertiesForCamera",NewName="/Game/Systems/Mover/Data/S_CharacterPropertiesForCamera")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/Data/S_CharacterPropertiesForTraversal",NewName="/Game/Systems/Mover/Data/S_CharacterPropertiesForTraversal")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/GM_Sandbox",NewName="/Game/Systems/Mover/GM_Sandbox")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/MovementModes/BP_MovementMode_Falling",NewName="/Game/Systems/Mover/MovementModes/BP_MovementMode_Falling")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/MovementModes/BP_MovementMode_Slide",NewName="/Game/Systems/Mover/MovementModes/BP_MovementMode_Slide")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/MovementModes/BP_MovementTransition_FromSlide",NewName="/Game/Systems/Mover/MovementModes/BP_MovementTransition_FromSlide")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/SmartObjects/AC_SmartObjectAnimation",NewName="/Game/Systems/Mover/SmartObjects/AC_SmartObjectAnimation")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/Data/S_MoverCustomInputs",NewName="/Game/Systems/Mover/Data/S_MoverCustomInputs")
|
||||||
|
+PackageRedirects=(OldName="/Game/Input/IA_Move",NewName="/Game/Core/PlayerController/Input/IA_Move")
|
||||||
|
+PackageRedirects=(OldName="/Game/Blueprints/MovementModes/BP_MovementTransition_ToSlide",NewName="/Game/Systems/Mover/MovementModes/BP_MovementTransition_ToSlide")
|
||||||
|
+PackageRedirects=(OldName="/Game/EnemyDetectBS",NewName="/Game/Systems/Movement/ASTShared/NPC/EnemyDetectBS")
|
||||||
|
+PackageRedirects=(OldName="/Game/Levels/LevelPrototyping/Meshes/SM_Cube",NewName="/Game/Systems/Movement/StateManager/Maps/LevelPrototyping/Meshes/SM_Cube")
|
||||||
|
|
||||||
@@ -9,6 +9,7 @@ FastReplication=False
|
|||||||
bDynamicReplication=False
|
bDynamicReplication=False
|
||||||
InvalidTagCharacters="\"\',"
|
InvalidTagCharacters="\"\',"
|
||||||
+GameplayTagTableList=/Game/Data/DT_DemoTags.DT_DemoTags
|
+GameplayTagTableList=/Game/Data/DT_DemoTags.DT_DemoTags
|
||||||
|
+GameplayTagTableList=/Game/Systems/Movement/StateManager/Blueprints/Data/AST_GameplayTagDT.AST_GameplayTagDT
|
||||||
NumBitsForContainerSize=6
|
NumBitsForContainerSize=6
|
||||||
NetIndexFirstBitSegment=16
|
NetIndexFirstBitSegment=16
|
||||||
+GameplayTagList=(Tag="Foley.Event.Handplant",DevComment="Game Animation Sample tags (Foley / SmartObjects)")
|
+GameplayTagList=(Tag="Foley.Event.Handplant",DevComment="Game Animation Sample tags (Foley / SmartObjects)")
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 2897 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user