Squelettes des anims AGIS, groupes de slots, bases de nage, WBP_PauseMenu, couverture et visuels MetaHuman tels qu'avant le rangement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
214 KiB
đïž Architecture du Projet â ProjectF
Ce document est la rĂ©fĂ©rence d'architecture du projet, destinĂ©e en prioritĂ© aux modĂšles d'IA (Claude, etc.) qui vont lire, modifier ou crĂ©er du contenu dans ce projet Unreal Engine. Il doit permettre de comprendre oĂč se trouve chaque systĂšme, quel fichier est responsable de quoi, et oĂč ajouter du nouveau contenu â sans avoir Ă explorer tout le projet Ă chaque session.
â ïž Ce document doit rester Ă jour. Voir la section 10. Maintenir ce document Ă jour et le skill
maintain-architecture-doc.
1. Vue d'ensemble du projet
1.1 Nature du projet
- Moteur : Unreal Engine 5.8.
- Aucun code C++ : il n'y a pas de dossier
Source/. Tout le gameplay est écrit en Blueprint visuel, dansContent/. - Genre : jeu de survie / extraction en vue 3e personne avec un inventaire en grille façon "Escape from Tarkov" (armure, sac à dos, armes, munitions, craft sur feu de camp/fonderie, générateurs, lecteurs de carte magnétique, coffres, PNJ pillables, véhicules).
- Multijoueur : le systÚme d'inventaire est répliqué (RPC client/serveur visibles partout dans
Inventory_Player, ex.Request Switch Weapon SERVER,Disarm Request SERVER). Le projet doit donc ĂȘtre pensĂ© serveur-autoritaire pour tout ce qui touche Ă l'inventaire, aux stats et au combat.
1.2 Les grandes couches du projet
Le projet est construit par empilement de trois grands blocs de contenu, plus une couche d'outillage IA :
-
Framework de personnage / locomotion ("Sandbox Character") â
Content/Systems/Blueprints/Basé sur le sample officiel Epic "Motion Matching" (pluginsMover,MotionWarping,MotionTrajectory,Chooser,AnimationLocomotionLibrary,AnimationWarping). GÚre le mouvement, la caméra, le Motion Matching, le traversal (vault/mantle/climb), les modes de mouvement personnalisés. Ce framework est en grande partie template/tiers : n'y toucher qu'en connaissance de cause. -
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. -
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 pontsPCG/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. -
Outillage IA â plugins
VibeUE,EditorToolset,ModelContextProtocol,Terminal(dĂ©clarĂ©s dansProjectFv1.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 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/).
1.3 Dépendances principales entre systÚmes
Character (Pawn, géré par le framework "Sandbox Character")
â
ââ Composant Inventory_Player (Content/Core/Coreinventory/Inventory_Player)
â ââ hĂ©rite de Inventory_Equipper (Ă©quipement d'armes/objets)
â ââ hĂ©rite de Inventory__Main (cĆur gĂ©nĂ©rique AGIS : slots, containers, rĂ©seau)
â
â â ïž Pour un item (`_BP_ItemBase` et enfants) qui a besoin de chercher/consommer un item dans
â l'inventaire de son porteur (ex. l'arc qui cherche des flĂšches), utiliser sa propriĂ©tĂ© hĂ©ritĂ©e
â `Owner Inventory` (fonction `Variables|Runtime|GetOwnerInventory`, self implicite) plutĂŽt que de
â reconstruire `GetOwnerCharacter â Cast SandboxCharacter_CMC â GetInventoryPlayer â GetListeningInventory` :
â cette derniĂšre chaĂźne se rĂ©sout Ă `None` tant que le joueur n'a pas ouvert son Ă©cran d'inventaire au
â moins une fois (`Listening Inventory` est un Ă©tat d'UI, pas l'inventaire persistant). `Owner Inventory`
â est typĂ©e `Inventory_Equipper` mais accepte directement les pins `Inventory__Main` (ex. `BOTH|FindItem`)
â grĂące Ă cette hiĂ©rarchie d'hĂ©ritage â aucun cast nĂ©cessaire. DĂ©couvert et corrigĂ© dans
â `BP_Item_Bow::CountArrows/ConsumeArrow` (voir §7).
â
â Inventory_Player pilote/possĂšde :
â ââ WB_InventoryScreen (UI d'inventaire complĂšte, créée Ă la demande)
â â ââ WB_InventoryPart1 / WB_InventoryPart2
â â ââ WB_EquipSlot â WB_Container â WB_InventorySlot â WB_Item
â ââ WB_QuickSelect (roue de sĂ©lection rapide d'Ă©quipement, 4 slots)
â ââ Les Input Actions IA_*AGIS via l'IMC_AGIS_Character / IMC_AGIS_InventoryTab
â
ââ Composant AC_Stats (Content/Systems/Stats/AC_Stats)
â ââ Vie, mort (OnDeath), Revive â dĂ©clenche WB_YouDied et le respawn du Character.
â TakeDamage(BodyPart, DMGValue) est le point d'entrĂ©e UNIQUE de toute cause de mort :
â utilisĂ© Ă la fois par la mort par chute et par la touche de debug K (SandboxCharacter_CMC/EventGraph).
â
ââ Armes (Content/Systems/Weapons/, voir §4.3)
â ââ AC_Weapon, ActorComponent ajoutĂ© Ă chaque Blueprint d'arme (BP_Item_Bow, BP_Item_AdvancedRifle) :
â s'auto-abonne (EventBeginPlay, cast Owner â BP_Item_HoldableBase) au dispatcher
â `BP_Item_HoldableBase::OnHeldStateChanged(bIsHeld)` â PAS Ă `_BP_ItemBase::OnOwnerChanged`
â (2026-09 : bug corrigĂ© â OnOwnerChanged se dĂ©clenche pour TOUT changement de propriĂ©taire,
â y compris le simple ramassage/rangement dans un slot d'inventaire non tenu en main, ce qui
â causait "2 armes Ă©quipĂ©es en mĂȘme temps" dĂšs que 2 armes Ă©taient prĂ©sentes dans l'inventaire.
â OnHeldStateChanged ne se dĂ©clenche que sur le VRAI changement d'Ă©tat main/pas-en-main, via
â `BPI_HoldableItem::On Item Attached(ShouldHold)` dĂ©jĂ implĂ©mentĂ© par BP_Item_HoldableBase).
â HandleHeldStateChanged(bIsHeld) â Equip(Owner)/Unequip() selon bIsHeld, qui pilotent `bIsEquipped`.
â Expose CanUse()/TryUsePrimary()/StopPrimary() (cooldown gĂ©nĂ©rique) que chaque item interroge dans ses
â overrides `Custom|PrimaryUse`/`StopPrimaryUsing` existants (voir §7). BFL_WeaponDamage::ApplyPointDamage
â route les dĂ©gĂąts d'un projectile vers `AC_Stats::TakeDamage` (mapping nom d'os â E_BodyPart).
â **SĂ©lection d'animation (2026-09-06)** : `Equip`/`Unequip` pilotent aussi `SandboxCharacter_CMC::Weapon`
â (enum `Weapon_Equip` : None/Bow/OneArmPistol/TwoArmPistol/Riffle/Bat â lu par la Pose Search Database
â `CHT_PoseSearchDatabases_Dense` pour sĂ©lectionner le pool d'animations armĂ©es/dĂ©sarmĂ©es de Motion
â Matching) et `isArmed` (bool) â ces deux variables existaient dĂ©jĂ sur le personnage mais n'Ă©taient
â JAMAIS renseignĂ©es avant ce fix (dette du template de base), donc la locomotion restait toujours
â "Ă mains nues" quelle que soit l'arme tenue. `AC_Weapon` porte une variable `WeaponTypeByte` (byte,
â 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
â `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
â distinctes cumulĂ©es, toutes deux dans `SandboxCharacter_CMC_ABP` :
â (1) `Get_MMInterruptMode` (utilisĂ©e par `Update_MotionMatching` pour choisir le `PoseSearchInterruptMode`
â passĂ© Ă `MotionMatchingAnimNodeLibrary.SetDatabasesToSearch`) ne testait QUE MovementMode/MovementState/
â Gait â jamais `Weapon_Equip` (variable ABP, distincte de `SandboxCharacter_CMC::Weapon`, alimentĂ©e depuis
â celle-ci via PropertyAccess dans `Update_States`, qui a bien SON PROPRE tracker `Weapon_Equip Last Frame`
â dĂ©jĂ prĂ©sent mais jamais branchĂ©). RĂ©sultat : passer armĂ©/dĂ©sarmĂ© EN RESTANT IMMOBILE ne changeait ni
â MovementMode/State/Gait, donc `Get_MMInterruptMode` retournait toujours `DoNotInterrupt` et Motion
â Matching continuait indĂ©finiment l'ancienne pose (`bIsContinuingPoseSearch=True`) sans jamais essayer
â la nouvelle base de donnĂ©es pourtant correctement sĂ©lectionnĂ©e dans `ValidDatabases`/`DatabasesToSearch`.
â Fix : condition supplĂ©mentaire `Weapon_Equip != Weapon_Equip Last Frame` ajoutĂ©e au `OR` racine de
â `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
â Ă©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`
â 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
â de toute façon minuscule), ce qui a dĂ©bloquĂ© la recherche. (3) **Lignes armĂ©es manquantes dans le
â chooser (CORRIGĂ 2026-09-06)** : la colonne `Is Armed` de `CHT_PoseSearchDatabases_Dense` (seule des 4
â tables LOD Ă en avoir une) n'avait que DEUX lignes `MatchTrue` â "Stand Idles Bow" (ligne 1) et "Stand
â Walks Armed" (ligne 3). Toutes les autres (courses 4-5, sprint 6, InAir 7, accroupi 8-9, prone 10-11,
â nage 12-17) exigeaient `MatchFalse`, donc AUCUNE ligne ne correspondait dĂšs qu'on courait/sautait/
â s'accroupissait armĂ© â chooser vide â Motion Matching gardait la derniĂšre pose (symptĂŽme : "mĂȘme
â animation en marchant, courant et accroupi"). Fix : ces lignes passĂ©es de `MatchFalse` Ă `MatchAny`
â (repli propre sur l'animation non-armĂ©e au lieu du gel ; les lignes 0 et 2 DOIVENT rester `MatchFalse`
â sinon elles masqueraient les lignes arc 1 et 3, l'Ă©valuation Ă©tant descendante premier-match-gagne).
â Aucun sous-chooser concernĂ© n'a de colonne d'arme, le repli est donc sans effet de bord.
â â ïž **RĂGRESSION 2026-09-13 (voir §8.2)** : `CHT_PoseSearchDatabases_Dense` a Ă©tĂ© ĂCRASĂ par la migration depuis
â `Project_F` â les lignes armĂ©es Bow (`PSD_Dense_Stand_Bow_Idles`, `_Bow_Aim_Idles`, `PSD_Walk_Bow`) et le passage
â `MatchFalse`â`MatchAny` dĂ©crits ci-dessus avaient disparu. **RESTAURĂ le 2026-09-14** : la version du commit `d29748b`
â a Ă©tĂ© remise (lignes Bow, Prone, nage, cover accroupi et Push revenues, contexte `Systems/Blueprints/SandboxCharacter_CMC_ABP`)
â puis le fix MatchAny a Ă©tĂ© refait par script : colonne `Is Armed` : lignes 0 et 2 en `MatchFalse`, 1 et 3 en `MatchTrue`, lignes 4 Ă 17 passĂ©es de `MatchFalse` Ă `MatchAny` (la ligne 18 l'Ă©tait dĂ©jĂ ), vĂ©rifiĂ© aprĂšs rechargement.
â **Reste un problĂšme de contenu NON corrigĂ©** (voir §9) : `PSD_Dense_Stand_Bow_Idles` â et ELLE SEULE
â (`_Bow_Aim_Idles`/`PSD_Walk_Bow`/`PSD_Crouch_Bow` sont sains) â a ses 4 entrĂ©es
â `DatabaseAnimationAssets[i].SamplingRange` rĂ©glĂ©es sur `(longueur_du_clip, longueur_du_clip)`, une
â fenĂȘtre de largeur nulle placĂ©e Ă la toute FIN du clip. Or Pose Search ne traite un asset comme
â bouclable que si sa plage vaut `(0,0)` (= « tout le clip ») : d'oĂč `bLoopAnimation=False` + fenĂȘtre de
â lecture nulle = une seule frame figĂ©e, alors mĂȘme que les AnimSequences sources sont bien `Loop=True`.
â Correction = remettre chaque `Sampling Range` Ă `0 / 0` dans l'Ă©diteur Pose Search Database â Ă faire Ă
â la main : la propriĂ©tĂ© n'est exposĂ©e par AUCUNE API (absente de `ObjectTools.list_properties`, refusĂ©e
â par `get/set_editor_property` ET `ObjectTools`, et le `SET` console ne cible qu'une classe entiĂšre donc
â toutes les databases chargĂ©es). C'est aussi ce dataset dĂ©gĂ©nĂ©rĂ© (4 poses uniques) qui faisait Ă©chouer
â le PCA du point (2).
â `PSD_Crouch_Bow` existe mais n'est rĂ©fĂ©rencĂ©e par AUCUN chooser (contenu orphelin) : une fois les
â SamplingRange corrigĂ©es, on pourra lui dĂ©dier une vraie ligne armĂ©e accroupie plutĂŽt que le repli.
â
ââ Composants de mouvement (Content/Systems/Movement/, Systems/Blueprints/MovementModes/)
â ââ AC_ClimbingComponent, AC_TraversalLogic, AC_PreCMCTick, AC_VisualOverrideManagerâŠ
â
ââ Couverture + interactions AST (Content/Systems/Movement/Cover|Interaction|StateManager|ASTShared, §4.2.5)
â ââ SandboxCharacter_Mover porte BPC_StateManager (hub d'Ă©tats) + BPC_CoverSystem + BPC_Interaction ;
â Get_MoveInput / Get_RotationMode / Get_Gait / Get_OrientationIntent / ProduceInput lisent le
â StateManager ; SandboxCharacter_Mover_ABP lie les calques OverlayGraph (tag Overlay) et InteractionIKGraph.
â
ââ Composant AIPerceptionStimuliSourceComponent (2026-09-05)
â ââ AjoutĂ© sur SandboxCharacter_CMC pour que le joueur soit dĂ©tectable par la vue de l'IA
â (AISense_Sight, auto_register_as_source=true). Sans lui, AUCUN AIPerceptionComponent
â ne peut jamais dĂ©tecter le joueur, quels que soient rayon/FOV/LOS configurĂ©s cĂŽtĂ© IA.
â
ââ Autres composants gameplay (BP_ScentPoint, etc. â voir Systems/Scent/ §4.3 et Systems/Wildlife/ §4.4)
Interactables (Content/Systems/Inventory/Interactables/*)
ââ ImplĂ©mentent BPI_Interactable, exposent un inventaire via un composant
Inventory_Storage / Inventory_Vendor / Inventory_Crafting (mĂȘmes bases AGIS que le joueur)
â consultĂ©s par Inventory_Player lors d'une interaction (touche IA_InteractAGIS)
Données d'items (Content/Data/Inventory_Data/, Content/Items/)
ââ DT_Items (DataTable), ItemDefaults / ItemInfo (structs), DD_Item (DataAsset par item)
alimentent Ă la fois l'UI d'inventaire ET les Blueprints d'objets sous Content/Items/BP_Item_*
Faune sauvage (Content/Systems/Wildlife/, voir §4.4)
ââ BP_AnimalBase (Character) rĂ©utilise TEL QUEL AC_Stats (vie/dĂ©gĂąts/mort, §1.3 ci-dessus) et
BP_ScentPoint (Systems/Scent/, §4.3) â aucun systĂšme de vie ni d'odeur parallĂšle n'a Ă©tĂ© créé.
BFL_WeaponDamage::ApplyPointDamage fonctionne automatiquement sur un animal (résout AC_Stats
par GetComponentByClass) : aucune adaptation nécessaire cÎté systÚme d'armes.
1.4 Conventions de nommage des assets
| Préfixe | Signification | Exemple |
|---|---|---|
BP_ |
Blueprint d'acteur | BP_Campfire, BP_Item_Helmet |
WB_ / WBP_ |
Widget Blueprint (UMG) | WB_InventoryScreen, WBP_PauseMenu |
AC_ |
ActorComponent | AC_Stats, AC_ClimbingComponent |
IA_ |
Input Action (Enhanced Input) | IA_InteractAGIS, IA_QuickSelectAGIS |
IMC_ |
Input Mapping Context | IMC_AGIS_Character |
E_ / EM_ |
Enum | E_MovementMode, EM_Road_Type |
S_ / ST_ |
Struct | S_TraversalCheckInputs, ST_Weather_Zone_forecasts |
M_ |
Material | M_Road, M_Campfire |
MI_ |
Material Instance | MI_Black, MI_Bottle |
SM_ |
Static Mesh | SM_Campfire, SM_RifleAdvanced |
SKM_ |
Skeletal Mesh | SKM_BodyArmor |
PA_ |
Physics Asset | PA_BodyArmor |
T_ |
Texture | T_Helmet |
RT_ |
Render Target | RT_InspectRenderer |
DT_ |
Data Table | DT_Items |
DD_ |
Data Definition (DataAsset) | DD_Item |
ML_ |
Macro Library (Blueprint) | ML_InventoryMacros |
SG_ |
SaveGame | SG_AGIS_UID, SG_AGIS_World |
GM_ / PC_ |
GameMode / PlayerController | GM_Sandbox, PC_Sandbox |
CR_ |
Control Rig | CR_ClimbingGraphV2 |
ABP_ |
Animation Blueprint | ABP_GenericRetarget |
AM_ |
Anim Modifier / Anim Montage | AM_ReloadHip |
NS_ |
Niagara System | NS_Tornado |
BPI_ |
Blueprint Interface | BPI_Interactable |
Le suffixe AGIS sur beaucoup d'assets (IA_InteractAGIS, WB_...AGIS, fonctions "Target is Inventory Player") signale qu'ils appartiennent au socle marketplace AGIS, par opposition aux ajouts spécifiques au projet.
1.5 Conventions importantes Ă respecter
- Ne jamais renommer/déplacer les assets du socle AGIS (
Content/Core/Coreinventory/, une bonne partie deContent/Systems/Inventory/,Content/UI/Inventory_UI/Widgets/WB_Container|WB_EquipSlot|WB_InventorySlot|WB_Item) sans nĂ©cessitĂ© â de nombreuses rĂ©fĂ©rences internes au plugin marketplace en dĂ©pendent. - Nouveau systĂšme de gameplay â crĂ©er un dossier dĂ©diĂ© sous
Content/Systems/<NomDuSysteme>/, Ă l'image deSystems/Stats/,Systems/Scent/,Systems/Movable_Object/. - Nouvel objet d'inventaire (item) â suivre le patron existant dans
Content/Items/: un BlueprintBP_Item_<Nom>(hĂ©ritant de_BP_ItemBaseou d'une base spĂ©cialisĂ©e dansItems/BaseBlueprints/), ses assets (mesh/matĂ©riau/texture) dans un sous-dossierContent/Items/<Nom>/ouContent/Items/Resources/<Nom>/, et une entrĂ©e dansDT_Items/ les DataAssets sousContent/Data/Inventory_Data/DataAssets/. - Nouvel Input Action liĂ© Ă l'inventaire â
Content/Systems/Inventory/Other/Inputs/Actions/, mappĂ© dansIMC_AGIS_CharacterouIMC_AGIS_InventoryTab. Input Action de dĂ©placement/camĂ©ra gĂ©nĂ©rique âContent/Core/PlayerController/Input/, mappĂ© dansIMC_Sandbox. - Nouveau widget d'inventaire â
Content/UI/Inventory_UI/Widgets/. Nouveau widget hors inventaire (HUD, menus) âContent/UI/Widgets/. - 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 dansInventory_Player.
2. Vue d'ensemble de l'arborescence racine
ProjectF/
âââ .gitattributes â RĂšgles Git (LFS, line-endings)
âââ .gitignore â Exclut Binaries/, Intermediate/, Saved/, DerivedDataCache/, .vscode/âŠ
âââ .mcp.json â DĂ©clare le serveur MCP "unreal-mcp" (http://127.0.0.1:8000/mcp) utilisĂ© par les agents IA
âââ ProjectFv1.uproject â Fichier projet UE5.8 : liste des plugins activĂ©s (voir §1.2/§8)
âââ README.md â Description minimale du projet
âââ Architecture_Projet.md â CE DOCUMENT
â
âââ .claude/ â Skills et configuration Claude Code pour ce projet
â âââ skills/
â âââ maintain-architecture-doc/SKILL.md â Skill de maintenance de ce document (voir §10)
â
âââ .codex/, .cursor/, .gemini/, .vscode/ â Configuration d'IDE / d'agents IA tiers (mcp.json, config.tomlâŠ)
â
âââ Config/ â Configuration moteur & jeu (voir dĂ©tail §7)
âââ Content/ â Tous les assets du jeu (voir dĂ©tail §3 à §6)
âââ Docs/ â Documentation de systĂšmes : `PCG_RoutesPonts.md` (systĂšme PCG routes et ponts, §7), `PCG_Haussmann.md` (systĂšme PCG
â d'immeubles haussmanniens, §7), avec leurs captures de vĂ©rification (`*_captures/`)
â
âââ Binaries/, Intermediate/, Saved/, DerivedDataCache/ â GĂ©nĂ©rĂ©s par l'Ă©diteur, exclus de Git, jamais Ă Ă©diter/documenter
2.1 â ïž Fichiers centraux autrefois isolĂ©s Ă la racine de Content/ (rangĂ©s le 2026-09-13)
Quelques fichiers importants vivent directement sous Content/, hors de toute organisation par dossier â Ă connaĂźtre avant de chercher "oĂč est le personnage" ou "oĂč est le GameInstance" :
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_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).
âââ 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.
3. Content/Core/ â Socle inventaire (AGIS) + Player Controller + Tick
Le cĆur technique de l'inventaire et des entrĂ©es gĂ©nĂ©riques du joueur.
Content/Core/
âââ Coreinventory/ â CĆur du plugin AGIS (composants, donnĂ©es, sauvegarde)
â âââ Inventory__Main.uasset â ActorComponent BASE : logique gĂ©nĂ©rique de containers/slots, rĂ©plication rĂ©seau. Racine de la hiĂ©rarchie d'inventaire.
â âââ Inventory_Equipper.uasset â hĂ©rite de Inventory__Main : ajoute la logique d'Ă©quipement (armes/objets tenus en main)
â âââ Inventory_Player.uasset â hĂ©rite de Inventory_Equipper : composant d'inventaire du JOUEUR. Contient toute la logique spĂ©cifique projet ajoutĂ©e cette session (SelectQuickSlot, ToggleQuickEquip, GetQuickSlotItemInfo, graphe INPUTS avec tous les bindings Enhanced Input du joueur). (2026-09-05) `ToggleQuickEquip`/`GetQuickSlotItemInfo` (touches V/B) Ă©taient des stubs de prototype (PrintString uniquement, aucun appel d'Ă©quipement rĂ©el, plus un bool `bQuickSlotArmed` inversĂ©) â corrigĂ©s pour appeler rĂ©ellement `Inventory_Equipper::SwitchWeaponByUID`/`EmptyHands` (hĂ©ritĂ©s). `GetQuickSlotItemInfo` retourne dĂ©sormais aussi le `ContainerUID` du slot (WEAPON/WEAPON2/Speed1/Speed2) via `WBContainer::GetContainerUID`, nĂ©cessaire pour cibler `SwitchWeaponByUID`. B Ă©quipe/dĂ©sĂ©quipe donc rĂ©ellement l'item du slot prĂ©sĂ©lectionnĂ© par V (le slot doit dĂ©jĂ contenir un item via le drag&drop du paperdoll â la roue V/B ne fait que choisir PARMI les 4 emplacements dĂ©jĂ Ă©quipĂ©s, elle ne pioche pas dans l'inventaire gĂ©nĂ©ral). Nouvelle fonction `CycleQuickSlot()` (WeaponâWeapon2âSpeed1âSpeed2âWeaponââŠ) ajoutĂ©e pour fiabiliser la sĂ©lection : `WB_QuickSelect::EventConstruct` (Content/UI/Inventory_UI/Widgets/Other/WB_QuickSelect.uasset) l'appelle dĂ©sormais automatiquement Ă chaque pression de V (donc Ă chaque crĂ©ation de la roue), sans dĂ©pendre du clic sur un bouton de la roue (`BtnWeapon1` etc. â dont le fonctionnement en jeu n'a pas pu ĂȘtre confirmĂ©). Les boutons de la roue restent cĂąblĂ©s Ă `SelectQuickSlot` en plus, au cas oĂč le clic fonctionne rĂ©ellement.
â âââ Inventory_Storage.uasset â Inventaire des containers de stockage (coffres, trunk, etc.)
â âââ Inventory_Vendor.uasset â Inventaire des PNJ vendeurs
â âââ Inventory_Crafting.uasset â Inventaire des stations de craft (campfire, smelter, gĂ©nĂ©rateur)
â âââ BP_AttachmentHandler.uasset â ActorComponent gĂ©rant les attachements sur les armes (silencieux, lampe, chargeurâŠ)
â âââ CombatComponent.uasset â ActorComponent : logique de combat (tir, dĂ©gĂąts) liĂ©e aux armes AGIS
â âââ BP_SM_DroppedMesh.uasset â Acteur reprĂ©sentant un objet lĂąchĂ© au sol (mesh statique + interaction de ramassage)
â âââ ItemMesh_STATIC.uasset / ItemMesh_Skeletal.uasset â Acteurs gĂ©nĂ©rant le rendu 3D d'un item tenu/lĂąchĂ© (mesh statique ou squelettal)
â âââ DD_Item.uasset â DataAsset dĂ©crivant un item (rĂ©fĂ©rencĂ© par ItemDefaults)
â âââ FL_AGIS.uasset â Function Library : fonctions statiques utilitaires du plugin AGIS
â âââ ML_AGISDefaults.uasset â Macro Library : macros par dĂ©faut du plugin
â âââ ML_AGIS_UMG.uasset â Macro Library : macros dĂ©diĂ©es Ă l'UI (UMG)
â âââ ML_InventoryMacros.uasset â Macro Library : macros gĂ©nĂ©riques d'inventaire
â âââ GameInstance_AGIS.uasset â GameInstance de base du plugin (Ă©tat persistant entre les maps)
â âââ Gamemode_AGIS.uasset â GameMode de base du plugin (indĂ©pendant de GM_Sandbox, voir §4)
â âââ PlayerController_AGIS.uasset â PlayerController de base du plugin
â âââ SG_AGIS_UID.uasset / SG_AGIS_World.uasset â SaveGame : compteur d'UID uniques / Ă©tat persistant du monde (sauvegarde)
â
âââ 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
â âââ Input/
â âââ 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_Aim, IA_Interact, IA_ESC, IA_NextPawn, IA_Traverse, IA_TeleportToTarget,
â IA_SwimmingDeep, IA_TwinStick_AimDirection, IA_Move_WorldSpace, IA_Look_Gamepad,
â 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)
âââ BPI_TickManager.uasset â Interface implĂ©mentĂ©e par les acteurs qui veulent ĂȘtre "tickĂ©s" par le manager
âââ BP_TickManager.uasset â Acteur central qui distribue les ticks (probablement Ă frĂ©quence configurable)
âââ E_TickFrequency.uasset â Enum des frĂ©quences de tick disponibles
4. Content/Systems/ â SystĂšmes de gameplay
4.1 Systems/Inventory/ â Extension du socle AGIS pour ce projet
Content/Systems/Inventory/
âââ BP_Spawner.uasset â Acteur de spawn (probablement spawn d'items/loot en dĂ©but de partie)
âââ DT_Items.uasset â DataTable listant tous les items du jeu (clĂ© pour crĂ©er/reconnaĂźtre un item)
â
âââ Interactables/ â Tout ce que le joueur peut "interagir" avec (touche IA_InteractAGIS)
â âââ BP_EnemyPuppet.uasset â PNJ/mannequin pillable
â âââ BP_Vendor.uasset â PNJ vendeur (utilise Inventory_Vendor)
â âââ CraftingInteractables/
â â âââ Campfire/BP_Campfire.uasset â Station de cuisson/craft (feu de camp) + ses assets (mesh, matĂ©riaux)
â â âââ Smelter/BP_Smelter.uasset â Station de fonte de minerai + ses assets
â âââ FuelGenerator/BP_Generator.uasset â GĂ©nĂ©rateur Ă©lectrique (consomme du carburant)
â âââ KeycardReader/BP_KeycardReader.uasset â Lecteur de carte magnĂ©tique (dĂ©verrouillage)
â âââ Other/BP_SimpleDoor.uasset â Porte interactable simple
â âââ Storages/
â âââ BP_StorageBox.uasset, BP_Trunk.uasset, BP_SphereStorage.uasset, _BP_StorageBase.uasset â Coffres/contenants de stockage (hĂ©ritent de _BP_StorageBase)
â âââ Deadbody/BP_Deadman.uasset â Cadavre pillable
â
âââ Interfaces/ â Interfaces Blueprint (contrats partagĂ©s)
â âââ BPI_Interactable.uasset â Contrat pour tout objet interactible (implĂ©mentĂ© par tous les Interactables ci-dessus)
â âââ BPI_SlotWidgets.uasset â Contrat pour les widgets de slot d'inventaire
â âââ BPI_HoldableItem.uasset â Contrat pour un item tenable en main
â âââ BPI_WeaponAGIS.uasset â Contrat pour les armes
â âââ BPI_DamageFeedback.uasset â Contrat de retour visuel/sonore lors de dĂ©gĂąts
â âââ BPI_GameInstance_AGIS.uasset â Contrat exposĂ© par le GameInstance cĂŽtĂ© AGIS
â
âââ Other/ â Assets d'appoint de l'inventaire
â âââ Animations/ â Animations liĂ©es aux armes/mains nues (Jog, Rifle, TurnInPlace, WALK) â clips Motion Matching (MM_*) et montages (AM_*)
â âââ Fonts/ â Polices utilisĂ©es par l'UI d'inventaire
â âââ Inputs/
â â âââ Actions/ â **Toutes** les Input Actions liĂ©es Ă l'inventaire (IA_*AGIS), y compris IA_QuickSelectAGIS et IA_QuickEquipAGIS (sĂ©lection rapide, ajoutĂ©es pour ce projet)
â â âââ IMC_AGIS_Character.uasset â Mapping Context actif en jeu (personnage) : touches 1/2/3/4, F, V, B, etc.
â â âââ IMC_AGIS_InventoryTab.uasset â Mapping Context actif quand l'inventaire plein Ă©cran est ouvert
â âââ InspectCapture/ â Rendu d'inspection d'objet (RT_InspectRenderer + BP_InspectRenderer + M_Inspect)
â âââ Materials/ â MatĂ©riaux gĂ©nĂ©riques rĂ©utilisĂ©s par les items (MI_Black, MI_Red, M_Metal, M_OutlineâŠ)
â
âââ Utilities/ â Outils d'Ă©diteur (Editor Utility Widgets) pour la crĂ©ation de containers/inventaires
âââ EUW_ContainersCreator.uasset, EUW_WidgetToInventoryData.uasset
âââ Others/WB_ContainerSpecsUtility.uasset, WB_CreatorContainerUtility.uasset
4.2 Systems/Blueprints/ â Framework de personnage / locomotion ("Sandbox Character")
Contenu trÚs largement issu du sample Epic Motion Matching (plugins Mover, MotionTrajectory, Chooser, AnimationLocomotionLibrary). à traiter comme un framework tiers : préférer l'étendre plutÎt que le réécrire.
Content/Systems/Blueprints/
âââ BPI_SandboxCharacter_Pawn.uasset â Interface du Pawn joueur (point d'entrĂ©e du framework de locomotion). (2026-09-14) + fonctions du sample GASP pour le Mover : `AddTarget`, `RemoveTarget`, `Set_IsPlayingRootMotion`, `Set_PhysicsProfile`, sorties typĂ©es de `Get_MMIResult` / `Get_PropertiesForRagdoll`
âââ BPI_SandboxCharacter_ABP.uasset â Interface de l'Anim Blueprint du personnage. (2026-09-14) + `Get_Trajectory`, `Update_MMIConstraints`
âââ AC_TraversalLogic.uasset â ActorComponent : logique de traversal (vault/mantle/climb contextuel)
âââ AC_PreCMCTick.uasset â ActorComponent : logique exĂ©cutĂ©e avant le tick du mouvement (Mover/CMC)
âââ AC_VisualOverrideManager.uasset â ActorComponent : gestion des overrides visuels du personnage
âââ GM_Sandbox.uasset / PC_Sandbox.uasset â GameMode / PlayerController du framework de locomotion (indĂ©pendants de Gamemode_AGIS/PlayerController_AGIS, voir §3)
â
âââ Cameras/ â SystĂšme de camĂ©ra (Camera Rigs modulaires)
â âââ CameraAsset_SandboxCharacter, CameraDirector_SandboxCharacter, CHT_CameraRig
â âââ E_CameraMode.uasset, E_CameraStyle.uasset
â âââ Rigs/CameraRig_* (Close/Medium/Far Ă Aim/Freecam/Strafe, CrouchOffset, CollisionOffset, TwinStickâŠ)
â
âââ MovementModes/ â Modes de mouvement personnalisĂ©s (plugin Mover)
â âââ BP_MovementMode_Walking / _Falling / _Slide
â âââ BP_MovementTransition_ToSlide / _FromSlide
â âââ BP_ClimbingMode.uasset
â
âââ ControlRigs/CR_Biped_FootPlacement.uasset â Control Rig : placement des pieds (foot IK)
âââ RetargetedCharacters/ABP_GenericRetarget.uasset â Anim BP gĂ©nĂ©rique pour le retargeting
â
âââ AnimModifiers/ â Anim Modifiers (post-traitement de clips d'animation Ă l'import)
âââ AnimNotifies/ â Anim Notifies personnalisĂ©es (BP_AnimNotify_FoleyEvent*, BP_NotifyState_EarlyTransition/MontageBlendOut) + enums associĂ©s
â
âââ Data/ â Structs/Enums/Curves partagĂ©s par tout le framework de locomotion
â âââ E_Gait, E_Stance, E_MovementMode, E_MovementState, E_MovementDirection(Bias), E_RotationMode,
â â E_AnalogStickBehavior, E_ExperimentalStateMachineState, E_TraversalActionType
â â (2026-09-14, convergence §8.2) valeurs du sample ajoutĂ©es EN FIN d'enum : E_MovementMode += Ragdoll, Flying ;
â â E_ExperimentalStateMachineState += Debug Flying Loop. S_CharacterPropertiesForAnimation += BasedMovementDelta,
â â Weapon_Type (`Data/Enums/E_WaponType`) ; S_BlendStackInputs += Blend Curve. Ne jamais rĂ©ordonner ces enums (valeurs stockĂ©es par nom interne).
â âââ S_CharacterPropertiesForAnimation / _ForCamera / _ForTraversal, S_BlendStackInputs,
â â S_MoverCustomInputs, S_PlayerInputState, S_TraversalCheckInputs/Result,
â â S_TraversalChooserInputs/Outputs (contexte des choosers `CHT_TraversalMontages_CMC/_Mover`), S_ChooserOutputs
â â (contexte de `CHT_CMCCharacterAnimations`), S_MovementDirectionThresholds,
â â S_RotationOffsetCurveChooser_Inputs, S_DebugGraphLineProperties
â âââ Curve_RotationOffset_* , Curve_StrafeSpeedMap, CHT_RotationOffsetCurve â Curve Tables pilotant les offsets d'animation
â âââ BFL_HelpfulFunctions.uasset, BPI_InteractionTransform.uasset
â
âââ SmartObjects/ â IntĂ©gration du plugin SmartObject (points d'ancrage d'animation contextuelle)
â âââ CHPA_SmartObject, AC_SmartObjectAnimation
â âââ SmartObjectAnimationPayload, SmartObjectSelectionInputs/Outputs
â
âââ SandboxCharacter_CMC_ABP.uasset â Anim Blueprint principal du personnage joueur (pilotĂ© par `/Game/Core/Character/SandboxCharacter_CMC`). Anciennement Ă©garĂ© dans un dossier `d/` mal nommĂ© â dĂ©placĂ© ici (nettoyage du 2026-09-04).
â
âââ (SUPPRIMĂS de ce dossier) SandboxCharacter_Mover / _ABP / _Ragdoll â **Depuis le 2026-09-13 ces trois assets n'existent plus dans `Systems/Blueprints/`** : les versions actives (personnage Mover conservĂ© Ă la demande de l'utilisateur) sont dans `Content/Systems/Mover/` (voir §4.2.1). `SandboxCharacter_CMC` (`Content/Core/Character/`) reste le personnage RĂEL du jeu. VĂ©rifiĂ© le 2026-09-14 : `GM_Dev` (GameMode de `MapDev1`), `Systems/Blueprints/GM_Sandbox` et `Core/Coreinventory/Gamemode_AGIS` ont `DefaultPawnClass = /Game/Core/Character/SandboxCharacter_CMC` ; `GM_Sandbox_Ragdoll` et `GM_MoverTest` (contenu de test du sample) restent Ă `None` ; `Systems/Mover/GM_Sandbox` spawne `SandboxCharacter_Mover`.
â
âââ GM_Sandbox_Ragdoll.uasset â Variante de `GM_Sandbox` avec `SandboxCharacter_Mover_Ragdoll` comme pawn par dĂ©faut (contenu du sample, non utilisĂ©e par le jeu rĂ©el).
â
âââ AI/StateTree/ â **(2026-09-08)** StateTree + tĂąches pour l'interaction Smart Object du personnage (`ST_Player_SandboxCharacter_SmartObject`, `STT_CharacterIgnoreCollisionsWithOtherActor`, `STT_FindSlotTransforms`, `S_SmartObjectPayload`). Contenu du sample, AI/SmartObject non branchĂ© sur le gameplay AGIS.
â
âââ (2026-09-08) Contenu supplĂ©mentaire fusionnĂ© depuis un import du sample officiel Epic **Game Animation Sample** (voir note globale en fin de §8) : `RetargetedCharacters/` (BP_Echo, BP_Manny, BP_Quinn, BP_Twinblast, BP_UE4_Mannequin â **supprimĂ©s le 2026-09-13** avec les personnages de dĂ©mo ; seul `ABP_GenericRetarget` subsiste), des `Cameras/Rigs/` et `MovementModes/` supplĂ©mentaires (`CameraRig_Far_Ragdoll`, `CameraRigPrefab_ThirdPerson`, `BP_MovementMode_Ragdoll`, `B_MovementMode_Flying`), des `Data/` supplĂ©mentaires (`S_RagdollProperties`, `S_MoverCustomInputs_Ragdoll`, `E_RagdollInjuryState`, `Ragdoll_Fall_to_Ground_BlendCurve`, variantes `S_CHT_*_IN/OUT` pour les choosers de traversal/interaction/get-up), des `AnimNotifies/` supplĂ©mentaires (`BP_NotifyState_MMI_IK`, `_MMI_MotionWarping`, `_OverrideCapsuleCollision`, `_OverrideMovementMode`, enums `E_EarlyTransition_*`/`E_FoleyEventSide`/`E_TraversalBlendOutCondition`), et des `SmartObjects/` supplĂ©mentaires (`Bench/`, `DistanceToSmartObject`, `PSS_SmartObject`, `TasksAndConditions/STT_ClaimSlot|ClearHandle|PlayAnimFromBestCost|PlayAnimMontage`).
4.2.1 Systems/Mover/ et Systems/Aiming/ â personnage Mover et framework du sample (isolĂ©s le 2026-09-14)
Copie du framework "Sandbox Character" du sample Epic Game Animation Sample, arrivĂ©e avec la migration Project_F (§8.2) et conservĂ©e pour le personnage alternatif basĂ© sur le plugin Mover et pour le systĂšme de visĂ©e. DĂ©placĂ©e SANS fusion depuis Content/Blueprints/ et Content/Input/. Beaucoup d'assets ont un homonyme dans Systems/Blueprints/ (AC_TraversalLogic, BPI_*, GM_Sandbox, PC_Sandbox, structs S_*, camĂ©rasâŠ) : ce sont des doublons DIVERGENTS, Ă ne pas confondre ni fusionner aveuglĂ©ment (voir §9, piĂšge consolidate_assets). Les enums, eux, sont partagĂ©s avec Systems/Blueprints/Data/ (fusionnĂ©s le 2026-09-14).
Content/Systems/Mover/
â ïž (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.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_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
âââ 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/`). (2026-09-27) `AC_VisualOverrideManager` rĂ©attache aussi les hitboxes du pion au MetaHuman (`AttachHitboxesTo`, voir §4.2.4)
âââ BPI_SandboxCharacter_Pawn / _ABP.uasset â Interfaces GASP implĂ©mentĂ©es par la chaĂźne Mover
âââ AI/StateTree/ â `ST_Player_SandboxCharacter_SmartObject` + tĂąches (copie GASP)
âââ AnimModifiers/ â `AM_BakePhaseCurveFromFootstepNotifies`, `AM_FootSteps_Run` (rĂ©fĂ©rencĂ©s par quelques anims `UEFN_Mannequin`)
âââ Cameras/ â `CameraAsset_SandboxCharacter`, `CameraDirector_SandboxCharacter`, `CHT_CameraRig`, `CameraShake_Basic`, `Rigs/CameraRig_*` (16)
âââ 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`
âââ 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`).
âââ 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/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 viaGetOwner) etArrow1(ArrowComponent,(0,0,90)/ yaw 90). â ïžArrow1DOIT ĂȘ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 deMoveAlongWall(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,MoveAlongWallne produit aucunAddMovementInputet 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égorieProne:IsProne,ProneHalfHeight(40),CrouchHalfHeight(55) ; catégorieSwimming:CurrentWaterBodyComp,IsSwimming,IsUnderwater,SwimSprint,WaterSurfaceZ,WaterDepth,SwimVerticalInput,SwimStartDepth(95),SwimStopDepth(80),SwimmingModeClass. - Prone :
IA_ProneâToggleProne(basculeIsProne+WantsToCrouch/WantsToStrafedansPlayerInputState), refusĂ© en nage ou en cover. La hauteur de capsule N'est PAS Ă©crite directement (contrairement au CMC qui faitSetCapsuleSize) :Apply_CrouchOrProne, appelĂ©e depuisOn_PreSimulateTick, rĂšgleStanceSettings.CrouchHalfHeight(40 en prone, 55 accroupi) et force un cycleUnCrouchâCrouchquand la capsule courante ne correspond pas â c'est leFStanceModifierdu plugin qui redimensionne la capsule, replace l'acteur et dĂ©cale le mesh.IA_Crouchen prone appelleExitProneToCrouch(retour accroupi). - Nage : les overlaps de la capsule (
OnComponentBegin/EndOverlapâ castWaterBody) renseignentCurrentWaterBodyComp;Update_Swimming(appelĂ©e depuisOn_PreSimulateTick, voir l'encadrĂ© « tick » plus bas) litGetWaterSurfaceInfoAtLocation(surface + profondeur), met Ă jourSwimSprint(depuisPlayerInputState.WantsToSprint) etSwimVerticalInput(valeurs brutes deIA_JumpâIA_Crouch), puisStartSwimming(profondeur â„SwimStartDepthâQueueNextMovementMode("Swimming")) /StopSwimming(<SwimStopDepthâFalling).IA_SwimmingDeepbasculeIsUnderwater(plongĂ©e). Le mode « Swimming » est enregistrĂ© au BeginPlay parAddMovementModeFromClass(variableSwimmingModeClass) et non dans la mapMovementModesdu composant : une instance créée par script dans le template du parent est privĂ©e et empĂȘchait la sauvegarde deSandboxCharacter_Mover_Ragdoll(« Illegal reference to private object »). - Cover (â ïž OBSOLĂTE depuis le 2026-09-27 :
AC_Covera Ă©tĂ© supprimĂ© et remplacĂ© par le systĂšme de couverture AST, voir §4.2.5 ; les variablesIn Cover/Cover/Edge L/R,ApplyCoverCrouchetUpdate_Coverrestent dans le BP mais ne sont plus alimentĂ©es) : l'Ă©vĂ©nementOnEntreredCoverd'AC_CoverrecopieInCover/cover/EdgeL/EdgeRsur le personnage puisApplyCoverCrouch(accroupi etWantsToStrafe= en couverture tant qu'on y est) ;IA_MoveappelleAC_Cover.MoveAlongWallquandIn Cover. Comme le Mover ignoreAddMovementInput,Get_MoveInputrenvoie, en cover,ConsumeMovementInputVector(le vecteur accumulĂ© par le composant).Update_Cover(On_PreSimulateTick) metCharacterMover.bAcceptExternalMovementĂ la valeur d'AC_Cover.InCover, sinon leMoveComponentTode 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'Arrow1tourne avec, le trace deMoveAlongWallrate 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 cetInputKeyest dĂ©portĂ© dans l'Ă©vĂ©nementToggleCoverd'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_PropertiesForAnimationrenvoie dĂ©sormaisStance= Swinning / SwinningDeep / Prone / Crouch / Stand, etGet_Gaitrenvoie Prone en prone, Swinning/SwinningSprint en nage.Get_MoveInpututilise la rotation camĂ©ra complĂšte (input 3D) en plongĂ©e comme en vol. Le chooserCharacters/UEFN_Mannequin/Animations/MotionMatchingData/CHT_PoseSearchDatabases_Moverest une copie du_Densedu CMC dont leContextDatapointe surSandboxCharacter_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 unBlend Poses by intdont 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 dePoseSearchDatabase,SetDatabasesToSearchles donne au nĆud, qui recherche chaque frame la meilleure pose d'aprĂšs la trajectoire (Update_Trajectory) â variablesValidDatabases,CurrentSelectedDatabase/Anim,MM Search Cost, rĂ©glagesGet_MMBlendTime/Get_MMInterruptMode. Voie 1 : Ă chaque entrĂ©e d'Ă©tat,SetBlendStackAnimFromChooserĂ©valueCHT_MoverCharacterAnimations_PoseMatch(chooser par clip, une ligne = une animation) qui renvoie UNE anim + ses rĂ©glages de blend, poussĂ©e dans leBlend Stackâ variablesStateName,BlendStackInputs,Search Cost,NoValidAnim. Dans les deux ABP l'index valait la constante0(Motion Matching en permanence) ; sur le Mover il passe par la variableAnimBranchIndex, qui vaut elle aussi0en 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 GASPDDCvar.UseExperimentalStateMachine/DDCvar.ExperimentalStateMachinen'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 surRagdoll/Flying+ ajout deSwimmingâSwimmingOnSurface. Effet de bord bĂ©nĂ©fique : le ragdoll du pion refonctionne (son Tick etEnteredRagdollSuccessfullyCheckcomparent le mode courant ĂRagdoll). - â ïž Tick du personnage Mover (corrigĂ© le 2026-09-18) :
SandboxCharacter_Moveret_RagdollavaientPrimaryActorTick.TickInterval = 30 s(le CMC est Ă 0). Tout leurEvent 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_Swimmingy Ă©tait branchĂ©e). Intervalle remis Ă 0 sur les deux pions, et par sĂ©curitĂ©Update_Swimming+Update_Coveront Ă©tĂ© dĂ©placĂ©es duEvent TickversOn_PreSimulateTick(dĂ©lĂ©guĂ© duCharacterMover, exĂ©cutĂ© Ă chaque pas de simulation). Si un jour le tick de ces pions est de nouveau throttlĂ© (politiqueBP_TickManager), la nage et la couverture continueront de fonctionner, mais lesUpdate_*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_SwimmingDeepMovingSprintont des lignes dont l'AnimAssetest None (log :OnGetComplete - Database None entry N has no associated animation asset), et la table imbriquéeSwimmingInDeepIdledu 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é dansCHT_PoseSearchDatabases_Mover: les lignes qui pointent sur une base vide (12, 14, 15, 17) sont rendues inatteignables (Stance = Pronealors queMovement Mode = Swimming, combinaison impossible par construction) et les deux lignes qui pointent surPSD_SwimmingMoving(13 pour Swinning, 16 pour SwinningDeep) passentMovement StateetGaiten 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 bienRM_Breastroke_overwater_01_*. - Vraie correction à faire à la main (impossible par script : la propriété
DatabaseAnimationAssetsd'unPoseSearchDatabaseet leResultsStructsd'unChooserTablene sont exposĂ©s ni au Python d'UE ni ĂObjectTools.set_propertiesâ seulescolumnsStructs/contextDatale sont) : ouvrir chaque base vide et y glisser les clips qui existent dĂ©jĂ sousAnimations/humain/SwimmingAnimation/âIDLE/IP_idle_underwater_01_Retargeted+IDLE/RM_Idle_turn_*pourPSD_SwimmingIdle,Swimming_animation/Crawl/RM_Crawl_*pourPSD_SwimmingMovingSprint,Swimming_animation/Breastok/RM_Breastroke_underwater_*pourPSD_SwimmingDeepIdle/Moving/MovingSprintâ puis remettre les lignes 12/14/15/17 du chooser sur leurStanced'origine (3, 3, 4, 4) et donner un rĂ©sultat Ă la table imbriquĂ©eSwimmingInDeepIdle. - 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ĆudMirrorde 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_Weaponne parlait qu'au CMC :Equip/Unequipfaisaient unCast To SandboxCharacter_CMC, qui Ă©choue sur le Mover (PawnvsCharacter, aucune classe commune). RĂ©sultat : arme bien en main, maisWeaponetisArmedjamais Ă©crits â locomotion dĂ©sarmĂ©e en permanence. Une brancheCast FailedâCast To SandboxCharacter_Movera Ă©tĂ© ajoutĂ©e dans les deux fonctions ; le CMC est inchangĂ©.- Nouvelle fonction
SandboxCharacter_Mover::SetEquippedWeapon(WeaponTypeByte)(appelĂ©e parAC_Weapon,0= dĂ©sĂ©quipement) : Ă©critWeapon_Equip(nouvelle variable, enumWeapon_Equip),isArmed(= byte â 0),WantToshot(remis Ă false au dĂ©sĂ©quipement) etWeapon. â ïž Trois enums d'arme coexistent dans le projet :Weapon_Equip(None/Bow/OneArmPistol/TwoArmPistol/Riffle/Bat â c'est l'espace deAC_Weapon::WeaponTypeByteet des colonnes du chooser de locomotion),E_WaponType(None/Riffle/Pistoll/Bow â c'est le type deSandboxCharacter_Mover::Weaponet du champS_CharacterPropertiesForAnimation.Weapon_Type, lu par les choosers d'aim offset deSystems/Aiming/) etE_WeaponType(inutilisĂ© ici).SetEquippedWeaponfait 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 isArmedsurTriggered, remis ĂfalsesurCompleted. C'est ce bool que lit la colonne « Want Toshot » du sous-chooserStand Idles Bowpour passer de l'idle arc Ă l'idle arc en visĂ©e. SandboxCharacter_Mover_ABPreçoit l'Ă©tat d'arme : nouvelles variablesWeapon_Equip,Weapon_Equip Last Frame,Want Toshot(+Is ArmedetIS Moving ObjectdĂ©jĂ prĂ©sentes), toutes alimentĂ©es en fin deUpdate_PropertiesFromCharacter(thread principal, comme le CMC le fait dans sonEventBlueprintUpdateAnimationâ surtout pas dansUpdate_Logic, qui peut tourner en thread-safe update).Is Armedde l'ABP =isArmedETWeapon_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 mettaitIs Armed = true, les lignes 0/2 du chooser (MatchFalse) Ă©taient rejetĂ©es, les lignes arc 1/3 Ă©chouaient sur leur colonneWeapon_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 chooserCHT_PoseSearchDatabases_Movern'Ă©tait consultĂ© que siStanceâ {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 sortieFalsedu Branch est en plus reliĂ©e ĂSetDatabasesToSearchpour que les deux chemins poussent bien leur liste dans le nĆud MM.Get_MMInterruptMode: ajout du termeWeapon_Equip â Weapon_Equip Last Framesur leORracine. 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: colonneIs ArmedrĂ©activĂ©e (elle avait Ă©tĂ© dĂ©sactivĂ©e le 2026-09-18 faute de propriĂ©tĂ© correspondante sur l'ABP Mover), colonneIS Moving ObjectrĂ©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 ») : colonneGaitpassĂ©e deMatchEqual WalkĂMatchAny. C'Ă©tait le dernier blocage : l'allure par dĂ©faut du personnage estRun, donc la ligne arc ne pouvait jamais matcher Ă l'arrĂȘt. (Le mĂȘme dĂ©faut existe dansCHT_PoseSearchDatabases_DensecĂŽ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).
Restant Ă faire :
- Aucune base Motion Matching armée pour le fusil / le pistolet (seul l'arc en a) ;
PSD_Crouch_Bowexiste mais n'est référencée par aucune ligne de chooser. SandboxCharacter_Movera désormais unAC_Statset ses capsules de hitbox (voir « Hitboxes calées sur le MetaHuman » en §4.2.4) ; il lui manque encore lePerceptionStimuliSourcedu CMC.- La visée n'a pas d'équivalent de
SandboxCharacter_CMC::ISaimingsur le Mover (seulsPlayerInputState.WantsToAimetWantToshotexistent).
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ĆudRetarget Pose From Mesh; sonEventBlueprintUpdateAnimationchoisit l'IKRetargeterdans la mapIKRetargeter_Mapen 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/test/Body/SKM_test_BodyMesh, gĂ©nĂ©rĂ© parIKRigController.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â sourceIK_UEFN_Mannequin, cibleIK_MetaHuman_test.auto_map_chains(EXACT)mappe tout sauf deux chaĂźnes, l'auto-caractĂ©risation MetaHuman nommantLeftFoot/RightFootce que le mannequin appelleLeftToe/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 ; orABP_GenericRetarget::UpdateRetargetProfileva chercher l'op nommĂ©e « Retarget IK Goals » (GetOpControllerFromRetargetProfileâ cast versIKRetarget_IKChains_Controller) pour moduler l'alpha d'IK par chaĂźne. Sans elle, le cast renvoie None etSetSettingsspamme 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 refaireassign_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 TagRTG_UEFN_to_MetaHuman_test) âFace(SKM_test_FaceMesh,ABP_Face_C) ; plus unMetaHumanComponentUE(BodyComponentName = "Body",FaceComponentName = "Face", post-processABP_Clothing_PostProcess). Pas de grooms : ce MetaHuman n'en a aucun d'assignĂ©.
Cùblage de la sélection :
GM_Sandbox(Systems/Mover/) reçoitBP_VisualOverride_MetaHumandansVisualOverrides_Soft.GM_Devest reparentĂ© surGM_Sandbox. C'Ă©tait unGameModeBasetotalement vide (aucune variable, aucun nĆud) qui ne servait qu'Ă fixerDefaultPawnClass; orAC_VisualOverrideManager::FindAndApplyVisualOverridefait unCast To GM_Sandboxâ sans ce reparentage, la DevMap n'appliquait jamais d'override (pire : le cast ratĂ© le remettait activement Ă zĂ©ro).DefaultPawnClass,PawnClasses_SoftetVisualOverrides_Softsont renseignĂ©s surGM_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Ă0dansConfig/DefaultEngine.inipour que le MetaHuman soit affichĂ© d'entrĂ©e. Repasser Ă-1(ou taperDDCvar.VisualOverride -1en 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 eventAddAttachedActorsToInventoryCapture, qui ajoute Ă la show-only list deSceneCaptureComponent2Dles composants de chaque acteur attachĂ© au pion (rĂ©cursif). Sans ça, les objets Ă©quipĂ©s (vĂȘtementsBP_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_BodyMeshlors 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 dansABP_GenericRetarget.IKRetargeter_Map, dupliquerBP_VisualOverride_MetaHumanen 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: composantsBPC_StateManager(tagStateManager),BPC_CoverSystem(tagCoverSystem),BPC_Interaction(tagInteractionSystem) â les tags sont obligatoires,StateActorComponent::SetComponentsretrouve 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: siCoverState â Noneâ pousse l'input brut dansStateManager.SetMovementInputAsVectorpuis renvoieBPC_CoverSystem.GetCoverMovement(0 pendant les transitions,CanCoverMovefaux).Get_RotationMode(â Strafe),Get_Gait(âStateManager.Get_Gait, qui met aussi Ă jour la collision de l'objet poussĂ©) etGet_OrientationIntent(â avant de l'acteur) sont court-circuitĂ©s quandCoverState â NoneouOverlayState = Pullpush.ProduceInput: synchroniseStateManager.SetInputCrouch(PlayerInputState.WantsToCrouch)etWantsToCrouch = joueur OR StateManager.Get_Crouch(couverture basse â accroupi).
- ABP
Systems/Mover/SandboxCharacter_Mover_ABP:Slot DefaultSlot â OverlayGraph (Linked Anim Graph, tag Overlay) â Dead BlendingetProcedural_FullBody â InteractionIKGraph â Pose History.Get/Set_InteractionTransformexistaient dĂ©jĂ (GASP 5.8). OverlayGraph::CanDynamicTransitionrenvoie toujours false : les transitions ALS (petits pas « Grounded Slot ») Ă©taient jouĂ©es en montage dynamique et, le slotGrounded SlotĂ©tant dansDefaultGroupdu squeletteSK_UEFN_Mannequinchez nous (groupe Ă partGroundedGroupchez 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Ă©erGroundedGroupet y dĂ©placerGrounded Slot(AST range aussiHitReactionSlotdansHitGroupet Fire/Legs/Arm R/Curves/Spine/Head/Arm L/Pelvis dansLayer) â non scriptable (SlotGroups non exposĂ© Ă Python).BPC_Interaction::Release PullPush Objectremet l'overlay sur None (AST : Default) pour retrouver l'Ă©tat de dĂ©part du perso.- VĂ©rifiĂ© en PIE (
Test/L_ASTCoverTest) : couverture basse et haute (entrée par montage motion-matché, glissement, demi-tour, sortie en reculant), porte, porte électronique, placard, levier, pousser/tirer.MapDev1: aucune erreur runtime liée à AST. - Restes connus : l'objet poussé passe 0,2 s en physique au relùchement et peut glisser ;
BP_MovementMode_WalkingAST(dĂ©cĂ©lĂ©ration instantanĂ©e en couverture) est portĂ© mais non utilisĂ© ; les os virtuels d'arme AST (VB RHS_WeaponTraceâŠ) manquent au squelette (avertissements de compilation d'OverlayGraph, sans effet hors armes AST) ; la visĂ©e depuis la couverture (UpdateCoverAim) n'a pas Ă©tĂ© testĂ©e.
4.3 Autres systÚmes de gameplay (ajouts spécifiques au projet)
Content/Systems/
âââ Stats/
â âââ AC_Stats.uasset â ActorComponent ACTIF : gĂšre la vie du personnage (Health), la mort (bIsDead, dispatcher OnDeath), Heal, Revive (voir §1.3). AjoutĂ© cette session pour le systĂšme de mort/respawn. (2026-09-05) Extension additive pour la faune : nouveau dispatcher `OnDamaged(BodyPart, DMGValue)`, diffusĂ© au point de convergence partagĂ© de `TakeDamage` (aprĂšs le switch par bodypart, avant le calcul de mort) â permet Ă un consommateur (ex. BP_AnimalBase) de rĂ©agir Ă CHAQUE coup reçu, pas seulement Ă la mort, sans dupliquer la logique de dĂ©gĂąts.
â
âââ Weapons/ (2026-09-05) â Architecture d'armes gĂ©nĂ©rique, rĂ©utilisable par toute arme (arc, arme Ă feu, futur mĂȘlĂ©e). Voir §1.3 pour le mĂ©canisme d'Ă©quipement.
â âââ AC_Weapon.uasset â ActorComponent commun Ă TOUTE arme (ajoutĂ© Ă BP_Item_Bow et BP_Item_AdvancedRifle). Ne contient AUCUNE logique spĂ©cifique Ă un type d'arme. Variables : bIsEquipped, bIsBusy, CooldownDuration, LastUseTime, OwnerCharacter. Dispatchers : OnEquipped/OnUnequipped/OnPrimaryUse(Stopped)/OnSecondaryUse(Stopped). Fonctions : CanUse(), Equip/Unequip, TryUsePrimary/StopPrimary, TryUseSecondary/StopSecondary. Son EventGraph s'auto-abonne Ă `OnOwnerChanged` de son propre acteur (pattern `Default|AssignOnOwnerChanged`) pour appeler Equip/Unequip automatiquement â zĂ©ro couplage avec Inventory_Player/Equipper.
â âââ BFL_WeaponDamage.uasset â Blueprint Function Library. `ApplyPointDamage(Target, Instigator, HitBoneName, Damage)` : rĂ©sout le composant `AC_Stats` de la cible (`GetComponentByClass` + cast, no-op silencieux si absent) et route vers `AC_Stats::TakeDamage`, en mappant le nom d'os touchĂ© (bones du squelette UEFN_Mannequin : head/neck_*âHead, thigh|calf|foot|ball_L/RâLeftLeg/RightLeg, clavicle|upperarm|lowerarm|hand_L/RâLeftArm/RightArm, tout le reste dont spine_*/pelvis/rootâTorso par dĂ©faut). RĂ©utilisable par toute arme/projectile/piĂšge futur.
â âââ BP_Projectile_Base.uasset â Actor projectile gĂ©nĂ©rique : StaticMeshComponent racine `ArrowMesh` (mesh + collision, PAS de mesh par dĂ©faut â Ă fournir par les enfants) + `ProjectileMovement`. `OnComponentHit` : ignore les hits sur son propre `Owner` (Ă©vite l'auto-hit au tir), appelle `BFL_WeaponDamage::ApplyPointDamage` puis `HandleImpact(Hit)` â fonction overridable (dĂ©faut : `DestroyActor`). Variable `BaseDamage` (instance-editable).
â âââ 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).
â âââ 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). (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). (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 + 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 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`) :
â âââ 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_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 `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
â dĂ©jĂ prĂ©sents sous Content/Characters/Animal/DeerStagAndDoe/ et Content/Animations/DeerAndDoe/) :
â âââ 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_* (`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`
â (`NavMeshBounds_Wildlife`, RuntimeGeneration = Dynamic â le mode par dĂ©faut `Static` ne (re)gĂ©nĂšre
â JAMAIS le NavMesh automatiquement, voir piĂšge §9). Ătend le NavMesh existant du niveau (aucun n'existait
â avant cette session).
â
âââ Door/
â âââ Garage_Door/BP_Garage_door.uasset â Porte de garage interactable
â âââ Simply_Door/BP_Simply_Door.uasset â Porte simple interactable
â
âââ Movement/
â âââ Climbing/AC_ClimbingComponent.uasset, CR_ClimbingGraphV2.uasset (Control Rig), CR_Mannequin_BasicFootIK.uasset, ClimbingMaterial.uasset
â âââ Cover/ â SystĂšme de couverture AST (copie du plugin AST_CoverSystem, §4.2.5). L'ancien `AC_Cover` a Ă©tĂ© supprimĂ© par l'utilisateur.
â â âââ Blueprints/Components/BPC_CoverSystem.uasset â Composant cover : `FindCoverWall` (capsule trace devant le perso vers un `CoverWallActor`), montage d'entrĂ©e choisi par Motion Matching (`CHT_IdleToCover`), `CoverMovement` (dĂ©placement le long de la spline), demi-tours (`CHT_TurnSide`), visĂ©e (`CHT_CoverAim`).
â â âââ Blueprints/Actors/CoverWallActor.uasset â RepĂšre de couverture INVISIBLE sans collision bloquante (spline + SplineMesh QueryOnly), Ă poser ~10 cm devant un vrai mur ; `HighCover` = mur haut (debout) sinon bas (accroupi).
â â âââ Blueprints/Interfaces/BPI_CoverSystem, BPI_CoverWall ; Structs/S_CoverMontage, S_CoverAimChooserInput, S_IdleToCoverChooserInput
â â âââ Character/Animation/ (HighCover/, LowCover/, Montages/, PSD_Cover, MotionMatchingData/CHT_*), Meshes/, Textures/
â âââ Interaction/ â SystĂšme d'interaction AST (copie d'AST_InteractionSystem, §4.2.5).
â â âââ Blueprints/ActorComponent/BPC_Interaction.uasset â Composant : sphĂšre de dĂ©tection (90 uu) â objet le plus proche (`StateManager.ClosestActor`), `CheckInteraction` â MoveTo par montage (`CHT_MovetoInteraction`) puis montage d'action ; pousser/tirer (`Grab/Release PullPush Object`, overlay PULLPUSH).
â â âââ Actors/DoorActor, ElectronicDoorActor, CupboardActor, LeverActor, PullPushObject â Interactifs Ă poser dans les maps (leurs points d'interaction sont des ChildActor `BP_Door`/`BP_Cupboard`⊠de ASTShared/Inventory).
â â âââ Blueprints/Enums, Interfaces, Structs, Data/CHT_MovetoInteraction ; Character/AnimationNotify (InteractionEvent, ANS_TrackInteractionIKLocation, AN_GrabPullPushObje)
â â âââ Character/Animations/ (Door, Cupboard, Lever, ElectronicDoor, MoveTo), Props/ (maillages porte/placard/levier)
â âââ StateManager/ â Copie INTĂGRALE du plugin AST_StateManager (~565 assets) ; seule une partie sert (â190 assets, §4.2.5). Le reste (cartes, camĂ©ras, poses d'armes, lootâŠ) est candidat au nettoyage.
â â âââ Blueprints/ActorComponent/StateActorComponent + BPC_StateManager â Hub d'Ă©tats AST (CoverState, InteractionState, OverlayState, entrĂ©es, ClosestActorâŠ), cherchĂ© par les autres composants via GetComponentByClass/tags.
â â âââ Character/Animations/AnimationLayers/OverlayGraph (+ OverrideOverlayLayer) â calque liĂ© (tag `Overlay`) : poses de couverture/pousser-tirer. `CanDynamicTransition` forcĂ© Ă false (transitions ALS dĂ©sactivĂ©es, §4.2.5).
â â âââ Character/Animations/AnimGraphs/InteractionIKGraph â calque liĂ© : IK des mains pendant les interactions.
â â âââ Blueprints/Data/AST_GameplayTagDT, AST_StateTreeGameplayTagDT â tables de tags `AST.*` (dĂ©clarĂ©es dans DefaultGameplayTags.ini).
â â âââ Inputs/IA_TakeCover (+ IMC_AST non utilisĂ©)
â âââ ASTShared/ â Sous-ensemble minimal (~44 assets) des plugins AST non portĂ©s, pour que StateManager/Interaction se chargent sans rĂ©fĂ©rences cassĂ©es : Inventory/ (E_ItemType, BPI_ItemBase, BPI_InventorySystem, BP_InteractionActorBase + BP_Door/BP_ElectronicDoor/BP_Cupboard/BP_Lever/BP_PullpushObject, InteractionWidget), Melee/, NPC/ (BPI_AIController, EnemyDetectBSâŠ), Parkour/ (interfaces, ParkourActor). Aucune logique de ces systĂšmes n'est active.
â âââ Test/L_ASTCoverTest.umap â Map de test : murs bas/haut + CoverWallActor, porte, porte Ă©lectronique, placard, levier, objet Ă pousser ; GameMode GM_Dev.
â
âââ Scent/BP_ScentPoint.uasset â Point Ă©metteur d'odeur, spawnĂ© par `SandboxCharacter_CMC::ScentFunct` (toutes les 2s pendant que le joueur se dĂ©place) et consommĂ© par `AC_AnimalSenses::CheckScent` (Systems/Wildlife/, §4.4). (2026-09-05) Deux bugs corrigĂ©s Ă la rĂ©utilisation par la faune : (a) `ScentFunct` ne crĂ©ait le point QUE via `SpawnActorFromClass`, sans jamais appeler son Ă©vĂ©nement `Custom|Create(life)` â la durĂ©e de vie (`TimeToLife`) restait donc Ă 0 ; ajout d'un appel explicite `Create(life=20.0)` juste aprĂšs le spawn. (b) Le dĂ©compte de durĂ©e de vie (`Custom|CustomEvent(DeltaTime)`) existait dĂ©jĂ mais n'Ă©tait appelĂ© par PERSONNE (`BeginPlay` enregistrait l'acteur auprĂšs de `BP_TickManager` mais rien n'invoquait rĂ©ellement l'event) â le point ne s'auto-dĂ©truisait donc jamais ; ajout d'un `EventTick` natif qui appelle directement ce Custom Event (Ă©vite de toucher au brancher `BP_TickManager` partagĂ©, hors-scope). Comparaison de fin de vie durcie de `== 0` Ă `<= 0` (float exact-equality fragile). Aucune nouvelle logique d'odeur créée â uniquement rĂ©paration du mĂ©canisme existant.
âââ Movable_Object/BP_Moveble_Object.uasset â Objet physique dĂ©plaçable par le joueur
âââ Interact_Interface.uasset â Interface d'interaction gĂ©nĂ©rique (racine de Systems/, Ă distinguer de BPI_Interactable dans Inventory/Interfaces/)
â
âââ 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)
âââ 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).
5. Content/Data/ â Structures de donnĂ©es globales
Content/Data/
âââ DataTable/DT_Season.uasset â DataTable des saisons (mĂ©tĂ©o)
â
âââ Enums/
â âââ E_CoverD.uasset, E_WeaponType.uasset
â âââ E_WaponType.uasset â (2026-09-14, venu de `Characters/UEFN_Mannequin/Animations/Props/`) type d'arme lu par les choosers d'aim offset de `Systems/Aiming/` et par `S_CharacterPropertiesForAnimation.Weapon_Type` ; volontairement NON fusionnĂ© avec `E_WeaponType`
â âââ Enums/E_BodyPart.uasset
â âââ Movement_enum/Weapon_Equip.uasset
â (â ïž Ă ne pas confondre avec Data/Inventory_Data/Enumerations/ ci-dessous â deux emplacements d'enums coexistent)
â
âââ Structure/Weather/ â Structs mĂ©tĂ©o (ST_Season, ST_WeatherZoneState, ST_Weather_Zone_CurentWeather/forecasts/_Data, ST_Zone_Influance)
â
âââ Inventory_Data/ â DonnĂ©es du systĂšme d'inventaire AGIS
âââ DataAssets/
â âââ 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
â âââ 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
âââ 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)
âââ ItemInfo, SlotInfo, SlotAddress, SlotAppearance, SubItemInfo, RandomSubItem
âââ ContainerInfo, ContainerAppearance
âââ AttachmentInfo, EquipSlot_KeySettings/_OwnContainersSettings/_TextureSettings/_TitleSettings
âââ ClientWidgetData, CombinedTexturesInfo, TextureInfo
âââ CraftingSlotRowInfo, DragSounds, DebugPrint, FindResult, InspectCameraInfo, InteractCosmetics, ItemActorInfo, MenuActions
âââ SaveStructures/SaveData_Player, SaveData_Storages, Savedata_ItemActor â Structures de sauvegarde (non encore branchĂ©es Ă un vrai systĂšme de save, voir §1.3 du systĂšme de mort)
6. Content/UI/ â Interfaces utilisateur
Content/UI/
âââ 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âŠ)
â âââ Widgets/
â âââ 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, 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_Item.uasset â Widget reprĂ©sentant un item posĂ© dans un slot â expose "Item Defaults" (struct ItemDefaults)
â â
â âââ InventoryMenu/
â â âââ 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_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_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
â â
â âââ LootWidgets/ â FenĂȘtres de pillage, une par type de source (Human, Storage, Vendor, Vehicle, Generator, KeycardReader) hĂ©ritant de _WB_LootWidgetBASE ; LootingCrafting/ pour les stations de craft
â â
â âââ MovableWindows/ â SystĂšme de fenĂȘtres dĂ©plaçables (_WB_Window_Base) : ItemInspect/ (inspection 3D d'un item), ItemInventory/ (fenĂȘtre d'inventaire flottante), WB_TitleBar_Window (barre de titre commune)
â â
â âââ Other/
â âââ WB_QuickSelect.uasset â đ Roue de sĂ©lection rapide (4 slots : Arme1/Arme2/Speed1/Speed2 + "Aucun"). RĂ©sout seule son Inventory_Player propriĂ©taire au Construct (GetOwningPlayerPawn â GetComponentByClass). Ouverte/fermĂ©e depuis Inventory_Player (touche V maintenue). Le graphe `INPUTS` d'Inventory_Player bascule aussi Input Mode/curseur/Ignore Look Input Ă l'ouverture/fermeture (mĂȘme pattern que `ToggleInventory`) â fix du 2026-09-04. **Cause rĂ©elle du bug (2026-09-04, deuxiĂšme fix)** : IA_QuickSelectAGIS/IA_QuickEquipAGIS (touches V/B) n'Ă©taient mappĂ©es QUE dans `IMC_AGIS_Character` (Systems/Inventory/Other/Inputs/), un Input Mapping Context jamais ajoutĂ© au joueur nulle part dans le projet (seule une variable `Input Mapping Context` orpheline sur Inventory_Player y faisait rĂ©fĂ©rence, sans AddMappingContext associĂ©) â donc l'input V n'atteignait mĂȘme pas l'Enhanced Input, avant tout problĂšme de widget. Fix : V et B ajoutĂ©s directement dans `IMC_Sandbox` (Core/PlayerController/Input/), l'unique IMC rĂ©ellement ajoutĂ© au joueur (via SandboxCharacter_CMC/SetupInput). `IMC_AGIS_Character` reste inutilisĂ©e â Ă nettoyer/fusionner un jour si confirmĂ© obsolĂšte.
â âââ WB_QuickGive.uasset â đ (2026-09-05) Menu debug "Quick Give" (touche F9, mappĂ©e dans `IMC_Sandbox` via `IA_QuickGiveAGIS`). Champ Item ID + Amount + bouton "Give" gĂ©nĂ©rique, plus des boutons raccourcis "Give Bow"/"Give 20 Arrows". Fonction `GiveItem(ItemID, Amount)` : rĂ©sout l'`Inventory_Player` du joueur possĂ©dant (`GetOwningPlayerPawn`+`GetComponentByClass`), construit un item via `FL_AGIS::Create Item Structure`, trouve un slot libre via `Inventory__Main::Find Space For Item`, puis le pose via `Inventory__Main::Set Item On Container` â mĂȘme chaĂźne AGIS bas niveau que celle utilisĂ©e en interne par `Reload Graph` de `BP_Item_AdvancedRifle`. Toggle (crĂ©er/`AddToViewport`+InputMode GameAndUI vs `RemoveFromParent`+InputMode GameOnly) cĂąblĂ© dans `SandboxCharacter_CMC::EventGraph` sur `IA_QuickGiveAGIS` (Started), variable `QuickGiveWidget` sur le Character. Outil de test, pas une fonctionnalitĂ© shippable.
â âââ WB_YouDied.uasset â Ăcran "Vous ĂȘtes mort" (systĂšme de mort/respawn)
â âââ WB_ActionScreen, WB_InteractScreen, WB_InteractBall, WB_PickupDisplay â Feedback d'interaction/pickup au sol
â âââ WB_CombatHUD, WB_DisplayHUD, WB_WeaponAmmoInfo â HUD de combat/munitions
â âââ WB_InventoryBackground, WB_ItemInfo, WB_SlotTitle â ĂlĂ©ments visuels d'appoint
â âââ WidgetTextures/ â IcĂŽnes des slots d'Ă©quipement (T_EquipSlot_*) et textures d'UI diverses
â
âââ TextureUI/M_CharacterUI.uasset, RT_CharacterView.uasset â Rendu de la vue personnage dans l'UI (ex. Ă©cran d'inspection du personnage)
â
âââ Widgets/ â UI HORS inventaire
âââ HUD/WB_HUD.uasset, WB_New_HUD.uasset, WB_New_InterfacePlayer.uasset
âââ PauseMenu/WBP_PauseMenu.uasset, WBP_Options.uasset
âââ interaction/WB_Interact.uasset
7. Content/Items/, Content/PCG/, Content/Maps/, Content/VFX/, Content/Prop/
Content/Items/ â Objets ramassables/Ă©quipables du jeu
âââ BaseBlueprints/
â âââ _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_Armor_Base.uasset â Base des items d'armure/Ă©quipement portĂ©
â âââ 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 /
â _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()`.
â **`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.
â **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
âââ ItemObjects/BPI_MergeableItemObject, ItemObject__BASE, ItemObject_ConsumableBASE, ItemObject_Magazine.uasset â Objets "monde" associĂ©s aux items (empilables, consommables, munitions)
â
âââ Ammo/ (Arrow), Weapon/ (Base_Bow, Base_knife), Tool/ (saucepan), Water/ (water_bottle),
â Food/ (Red_Apple, meat, cooked_Meat, Burnt_Meat), Resource/ (Stick, Stone)
â â Chaque sous-dossier contient les assets (mesh/matĂ©riau/texture/Thumbnail) d'un item ; les Blueprints correspondants sont soit Ă la racine d'Items/, soit dans Resources/. `Weapon/Base_Bow/Thumbnail` et `Ammo/Arrow/Thumbnail` ne contenaient que des icĂŽnes prĂ©parĂ©es Ă l'avance (2026-09-04) â item "Bow" et "Arrow" ajoutĂ©s dans DT_Items pour les utiliser (voir §5).
â
âââ Resources/ â Assets 3D (mesh/matĂ©riau/texture) groupĂ©s par Ă©quipement portĂ©, + cas particuliers
â âââ 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)
â âââ ABP_SkeletalEquippables.uasset â Anim Blueprint partagĂ© par les items squelettaux Ă©quipĂ©s
â
âââ ItemTextures/ â Textures d'icĂŽnes/inventaire communes Ă tous les items (T_*)
Content/PCG/ â GĂ©nĂ©ration procĂ©durale de contenu (plugin PCG)
âââ Haussmann/ â (2026-10-30) SystĂšme PCG d'immeubles haussmanniens (Paris 2127, abandonnĂ©s depuis 60 ans). Doc complĂšte :
â â `Docs/PCG_Haussmann.md`. Assemble les modules existants `/Game/ProjectF/Meshes/Facades|Facades_Variantes|Interieurs`
â â (SM_PF_HM_*, teintes MI_PF_HM_V_*_Gris/_Ocre), dĂ©cor RueDeParis/PropsParis/Megascans ; aucun mesh nouveau
â âââ Blueprints/BP_PF_Haussmann.uasset â Acteur : spline (façade ouverte, bĂąti Ă gauche, ou Ăźlot fermĂ©) + `PCG_Structure` (tag `HM_Structure`,
â â graphe PCG_PF_HM_Structure) + `PCG_Decoration`. Variables « PF » : `FacadeLength` (façade droite sans spline),
â â `Floors` (R+n), `BayWidth`, `BuildingBays`, `Depth`, `Degradation` (0..4), `Tint` (-1 = par immeuble), `bShopFront`.
â â Graine = Seed des composants (rĂ©sultat reproductible, vĂ©rifiĂ© par empreinte)
â âââ Graphs/PCG_PF_HM_Structure.uasset â Segments â pourtour (rue, cour, mitoyens) â travĂ©es/immeubles â Ă©tages â type par immeubleĂĂ©tage â
â â ruine (colonnes effondrĂ©es, toitures perdues) â Ă©tat par travĂ©e ; mansardes d'angle, chaĂźnes d'angle,
â â planchers, terrasson zinc, souches, battants, gravats ; intĂ©rieurs : cage d'escalier (travĂ©e de porte cochĂšre),
â â murs entre immeubles, appartements (refend rue/cour, cloisons, portes). ISM avec collision. Sa sortie alimente la dĂ©coration
â âââ Graphs/PCG_PF_HM_Decoration.uasset â Lit la sortie de la structure (Get Actor Data, tag HM_Structure) : lierre, herbes, dĂ©tritus, gravats
â â d'Ă©tage, enseignes ; sans collision. GĂ©nĂ©rer la structure AVANT la dĂ©coration
â â Les deux graphes sont gĂ©nĂ©rĂ©s par script (`E:/projet/PF_Haussmann_Work/scripts/ue_hm_graph_*.py`) : les modifier lĂ
â âââ Data/ST_PF_HM_* + DT_PF_HM_*.uasset â ParamĂštres centralisĂ©s : DT_PF_HM_Levels (Ă©tages par Floors), DT_PF_HM_Degradation (H0-H4),
â â DT_PF_HM_Tints, DT_PF_HM_Types (type de module par KindĂRole), DT_PF_HM_Variants (mesh/matĂ©riau pondĂ©rĂ©s
â â par TypeIdĂteinteĂdĂ©gradation), DT_PF_HM_LeafSlots (charniĂšres des battants), DT_PF_HM_Tiles.
â â Source CSV unique : `E:/projet/PF_Haussmann_Work/scripts/hm_data_csv.py` (+ `ue_hm_data.py` pour rĂ©importer)
â âââ Maps/L_PF_HaussmannTest.umap â Niveau de test non partitionnĂ© : 8 variantes (H0 Ă H4, R+4 Ă R+7, FacadeLength, Ăźlot fermĂ©, immeuble d'angle)
âââ RoadNetwork/ â (2026-10-28/29) SystĂšme PCG de routes et ponts post-apo (France 2127). Doc complĂšte : `Docs/PCG_RoutesPonts.md`
â âââ Blueprints/BP_PF_Road.uasset â Route : spline + `PCG_Structure` (PCG_PF_Road_Structure) + `PCG_Decoration` (PCG_PF_Road_Decoration). Variables
â â `Profile` (Name, ligne de DT_PF_RoadProfiles), `Degradation` (0..3), `bSnapToLandscape`. Graine = Seed du composant PCG
â âââ Blueprints/BP_PF_Bridge.uasset â Pont : spline (2 points) + PCG_PF_Bridge_Structure / _Decoration. `BridgeType`, `Degradation` (0..4),
â â `CollapsedSpan` (-1 = tirĂ©e par la graine), `bWalkable` (passerelle de fortune), `bVehicleTraversable` (barrage)
â âââ Blueprints/BP_PF_RoadNetwork.uasset â Un par niveau : dalles de carrefour (PCG_PF_Network). DĂ©sactivĂ© (couche JunctionPad vide) : les croisements sont faits par la variante J des routes
â âââ Graphs/PCG_PF_*.uasset â Les 5 graphes (structure route, dĂ©coration route, structure pont, dĂ©coration pont, rĂ©seau). GĂ©nĂ©rĂ©s par
â â script (`ProjetF blender/RoadNetwork/scripts/ue_rn_graph_*.py`) : les reconstruire par script plutĂŽt qu'Ă la main
â âââ Data/ST_PF_* + DT_PF_*.uasset â ParamĂštres centralisĂ©s : DT_PF_Variants (toutes les variantes pondĂ©rĂ©es par couche/famille/niveau),
â â DT_PF_RoadProfiles, DT_PF_Degradation (R0-R3, B0-B4), DT_PF_Bands (bandes latĂ©rales), DT_PF_BridgeTypes,
â â DT_PF_BridgeModules. Source CSV : `rn_data_csv.py` (+ `ue_rn_data.py` pour rĂ©importer)
â âââ Meshes/Road|Equipment|Bridge/ â Segments de route (7 profils Ă 8 variantes), carrefours, panneaux FR, bornes, J6, glissiĂšres (spline meshes de 4 m), blocs,
â â dĂ©bris, modules de ponts (travĂ©es D0/D1/D2/effondrĂ©e, piles, culĂ©es, passerelle, barrage) â gĂ©nĂ©rĂ©s dans Blender
â âââ Materials/ â M_PF_Road (couches par couleurs de sommets + marquages), M_PF_Structure (triplanaire), M_PF_Sign,
â â M_PF_DecalMesh (inutilisĂ© : couche Decal dĂ©sactivĂ©e) + Instances/MI_*
â âââ Textures/ â T_PF_* (surfaces Fab/Megascans 2K, atlas de panneaux, masques de decals)
â âââ Maps/L_PF_RoadBridgeTest.umap â Niveau de test World Partition des 9 scĂ©narios (terrain 1 kmÂČ, riviĂšre, ruisseau, vallĂ©e) + ses couches HLOD gĂ©nĂ©rĂ©es
âââ Road/ â Prototype antĂ©rieur (une route, conservĂ© tel quel, instance dans MapDev1). RemplacĂ© par RoadNetwork/ pour les nouvelles routes
â âââ PCG_Road.uasset â Graphe PCG gĂ©nĂ©rant la route procĂ©durale (matĂ©riaux vieillis/mousse/humiditĂ©, potholes via GeometryScript)
â âââ BP_AbandonedRoad.uasset â Acteur portant le graphe PCG
â âââ M_Road.uasset, ST_Road_data.uasset, EM_Road_Type.uasset â MatĂ©riau, struct de donnĂ©es et enum de types de route
âââ 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/
âââ MapDev1.umap â đșïž Map de dĂ©veloppement PRINCIPALE (GameDefaultMap / EditorStartupMap, voir Config/DefaultEngine.ini)
âââ GM_Dev.uasset â GameMode utilisĂ© sur MapDev1 (hĂ©rite directement de GameModeBase, indĂ©pendant de GM_Sandbox/Gamemode_AGIS)
âââ pcg_Test_Dev.umap â Map de test PCG
âââ PCG_Test_Dev_HLODLayer_*, Untitled_HLOD0_Instancing.uasset â Assets HLOD gĂ©nĂ©rĂ©s pour les maps de test
Content/VFX/
âââ 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)
âââ M_Blood.uasset, T_Blood.uasset â Effet de sang
âââ 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
8. Assets tiers / bibliothĂšques (peu ou pas de logique de gameplay)
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.
Content/Animations/ â Clips de mocap tiers : DeerAndDoe/, Fox/, Wolf/, humain/ (Armed_mov, Avoid, Carrying, Cover,
Effect_Animation, INteraction, Prone, Push, SwimmingAnimationâŠ)
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,
MotionMatchingData/ [Channels, Databases, Normalization_Sets, Schemas], Poses, Run, Slide,
Sprint, Traversal, Walk, Rigs, Materials, Meshes, Textures)
Content/Fab/ â Assets Fab/Quixel Megascans : MaterialFunctions/, MaterialParameterCollection/, Materials/
(Standard/VT), Megascans/Plants/ (Common_Hemp_Nettle, Wild_Grass Ă2), Megascans/Surfaces/
(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,
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
d'échecs d'auto-save « Illegal reference to private object »). Corrigé le 2026-09-04 en créant de
vraies `MaterialInstanceConstant` (parent `/InterchangeAssets/gltf/Substrate/M_GLTF`) avec les
mĂȘmes textures. Si un futur import Fab/glTF Ă©choue Ă l'auto-save de la mĂȘme façon, vĂ©rifier le(s)
slot(s) de matĂ©riau du StaticMesh importĂ© pour ce mĂȘme symptĂŽme.
â ïž **2026-09-05** : aprĂšs une coupure de courant, `survival_kit_bow.uasset` (StaticMesh) s'est retrouvĂ©
avec 0 vertex/0 triangle/bounds nuls (asset vidé, probablement une sauvegarde tronquée en cours
d'Ă©criture) â l'arc n'avait plus de mesh visible ni de collision en jeu. Diagnostic : toujours
vérifier `mesh.get_num_vertices(0)` / `get_bounds()` aprÚs une fermeture anormale de l'éditeur sur
un asset suspect avant de chercher ailleurs. Fix : ré-import depuis la source Fab d'origine
(chemin retrouvé via `mesh.get_editor_property("asset_import_data").extract_filenames()`, cache
`%LOCALAPPDATA%/Temp/FabLibrary/<guid>/`) vers un dossier scratch, puis renommage vers
`.../StaticMeshes/survival_kit_bow_fixed` (le nom d'origine `survival_kit_bow` n'a pas pu ĂȘtre
réutilisé : `delete_asset`/`consolidate_assets` échouaient silencieusement sur l'asset corrompu
malgrĂ© 0 rĂ©fĂ©renceur restant â laissĂ© orphelin en l'Ă©tat, sans danger). Toutes les rĂ©fĂ©rences
(`BP_Item_Bow::ItemMesh_STATIC`, `DT_Items` ligne "Bow" â `Spawner Preview Mesh`) repointĂ©es vers
`survival_kit_bow_fixed`. Le socket `ArrowSocket` a dĂ» ĂȘtre recréé (perdu avec l'ancien asset).
Content/KitFR/ â Kit modulaire de bĂątiments français post-apo (gĂ©nĂ©rĂ© dans Blender : `ProjetF blender/Kit_Habitat_FR.blend`,
export `UE_Export/Kit_FR`, import `kit_fr_scripts/ue_import_kit.py`). Meshes/<Style>/SM_FR_*_S0..S4,
3 maĂźtres M_KitFR_Opaque/Masked/Glass + Materials/Instances/MI_* , Textures/ (Megascans 2K + CC0).
**2026-10-28** : rĂ©importĂ© aux MĂMES chemins (niveaux non cassĂ©s) avec textures Megascans,
normales OpenGL â `flip_green_channel`, tuiles `TileSizeU/V`, AO branchĂ©e ; 88 anciennes textures
CC0 et 8 doublons `SM_FR_*_Floor_S0_001` supprimés. Dossier NON versionné dans git à cette date.
Content/ProjectF/ â **(2026-10-28)** Assets « Project F » (`ProjetF blender/ProjectF_Assets`, lots 1â5 + prototype, SANS les
véhicules) : Meshes/<Lot>/SM_PF_* (224, Nanite sauf meshes avec verre, UCX sinon collision complexe),
Maps/L_PF_Demo (prĂ©sentation). MatĂ©riaux PRĂCALCULĂS dans Blender (`Scripts/pf_bake.py`) sur l'UV1 :
1 MI par asset de `M_PF_Baked` (BC + RMA = rugosité/métal/opacité + NO = normale espace OBJET,
Transform LocalâWorld, donc indĂ©pendante des tangentes de l'UV0) ; verre `M_PF_BakedGlass`
(translucide) ; decal `M_PF_DecalCoulure` (masqué, UV0). Les slots papier peint/gravats/sombre
utilisent les MI de /Game/KitFR. Import : `ProjectF_Assets/Scripts/ue_import_pf.py`
(Ă©tapes textures â masters â mis â meshes). **Variantes** (prĂ©calculĂ©es aussi) : `MI_PF_<asset>_<Gris|Ocre>`
(teintes de pierre, 42 modules lot 2b) et `MI_PF_<asset>_<Sec|Humide>` (piÚce sÚche/infiltrée,
26 assets lot 4) â mĂȘmes slots que la version par dĂ©faut : les appliquer en surcharge de matĂ©riau
sur l'instance placée (exemples dans L_PF_Demo, acteurs tagués `PF_VARIANTES`, script
`Scripts/ue_pf_demo_variants.py`).
Content/Bridges/ â Kits de ponts gĂ©nĂ©rĂ©s dans Blender (Truss, Bailey, Geo ; `ProjetF blender/UE_Export/README.md`) : travĂ©es D0-D3,
piles, culées, ponts entiers, un graphe PCG par kit. Le systÚme PCG/RoadNetwork réutilise les travées Truss
(type `MetalAncien`). Dossier NON versionné dans git (2026-10-29).
Content/Megaplant_Library/ â VĂ©gĂ©tation Megaplant : Plant_Bilberry/, Tree_European_Aspen/, Tree_Hornbeam/
(chacun avec Instances/, Materials/, Textures/)
Content/Audio/Foley/ â **(2026-09-08)** SystĂšme de sons de pas/foley du sample Game Animation Sample :
`AC_FoleyEvents` (ActorComponent, ajouté à `SandboxCharacter_Mover`, voir §8.2),
`S_FoleyEventParams`, `DefaultFoleyEventAudioBank`. Reste du dossier `Content/Audio/` :
sons/bancs audio divers du sample, non branchés sur le gameplay AGIS.
Content/MetaHumans/ et Content/Characters/Echo|Paragon|UE4_Mannequin|UE5_Mannequins/ â **SUPPRIMĂS le 2026-09-13**
(nettoyage) : assets MetaHuman et personnages de démonstration du sample Game Animation
Sample (~2,6 Go), utilisés uniquement par les BP de démo `RetargetedCharacters/BP_*`
(supprimés aussi). Copie de sauvegarde : `E:\projet\ProjectFv1_backup_migration_2026-09-13\nettoyage_etape1_demo\`.
`UEFN_Mannequin` reste le seul squelette de personnage humanoĂŻde du projet.
Content/Levels/, Content/Widgets/, Content/dev_map â **SUPPRIMĂS le 2026-09-14** : dĂ©mo du sample Game Animation Sample (kit de blockout
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).
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)
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).
â Ces deux derniers dossiers ne doivent JAMAIS ĂȘtre Ă©ditĂ©s ou documentĂ©s Ă la main :
leur contenu suit automatiquement les maps et les acteurs qu'elles contiennent.
8.1 Import du sample Epic "Game Animation Sample" (2026-09-07/08)
L'utilisateur a importĂ© le contenu brut du sample officiel Epic Game Animation Sample directement dans Content/Blueprints/ (structure de dossier d'origine du sample), dans le but de disposer d'une rĂ©fĂ©rence complĂšte/fonctionnelle du framework "Sandbox Character" (voir §4.2) pendant que sa migration vers le plugin Mover Ă©tait en cours. Ce sample est la source originelle du framework Systems/Blueprints/ dĂ©jĂ prĂ©sent dans ce projet : l'import a donc créé 95 collisions de nom exactes (mĂȘmes noms : SandboxCharacter_CMC, AC_TraversalLogic, BP_MovementMode_Walking, E_Gait, IMC_Sandbox, tous les IA_* gĂ©nĂ©riques, etc.) entre le contenu fraĂźchement importĂ© et les versions dĂ©jĂ personnalisĂ©es de ce projet.
Politique appliquĂ©e (dĂ©cision utilisateur explicite) : garder la version du projet partout, ne conserver du nouvel import que le contenu rĂ©ellement nouveau (RetargetedCharacters, SmartObjects/AI supplĂ©mentaires, Ragdoll, Audio/Foley, MetaHumans, Characters de dĂ©mo â voir §4.2/§8). Les 95+17 doublons (17 supplĂ©mentaires dĂ©couverts aprĂšs coup sous Content/Input/ et Content/Data/, dont IMC_Sandbox lui-mĂȘme) ont Ă©tĂ© fusionnĂ©s via EditorAssetLibrary.consolidate_assets() (redirecteur automatique + suppression du doublon) quand c'Ă©tait possible, ou supprimĂ©s directement (delete_asset) quand rien ne rĂ©fĂ©rençait plus la copie importĂ©e. Le contenu unique restant a ensuite Ă©tĂ© dĂ©placĂ© vers son emplacement dĂ©finitif (Content/Systems/Blueprints/, Content/Core/PlayerController/Input/) via AssetToolsHelpers.get_asset_tools().rename_assets() (dĂ©placement avec réécriture de toutes les rĂ©fĂ©rences, pas un dĂ©placement de fichier brut).
Reste Ă faire / connu (2026-09-08) :
Content/Systems/Mover/SmartObjects/AC_SmartObjectAnimation(anciennementContent/Blueprints/SmartObjects/, dĂ©placĂ© le 2026-09-14) : un doublon n'a pas pu ĂȘtre fusionnĂ©/supprimĂ© (l'outilconsolidate_assetsfait planter l'Ă©diteur sur cet ActorComponent prĂ©cis, voir §9) â laissĂ© en l'Ă©tat intentionnellement, sans impact gameplay (fonctionnalitĂ© SmartObject annexe).- â ïž ObsolĂšte depuis le 2026-09-13 (voir §8.2) â
Content/Blueprints/contenait alors de nombreux fichiersObjectRedirector(rĂ©sidus deconsolidate_assets) â passer un "Fixup Redirectors" manuel (clic droit sur le dossier dans le Content Browser) quand pratique ; aucune API Python trouvĂ©e pour cette opĂ©ration, et forcer une suppression brute des redirecteurs risquerait de casser des rĂ©fĂ©rences logicielles (soft references) non encore réécrites.
8.2 Migration Project_F â ProjectFv1 (2026-09-13) â incident et Ă©tat aprĂšs rĂ©paration
E:\projet\Project_F est un autre dĂ©pĂŽt git (projet Game Animation Sample nettoyĂ©, oĂč l'utilisateur a dĂ©veloppĂ© un systĂšme de visĂ©e). Le 2026-09-13 (~22:00â22:12), l'Ă©diteur de Project_F a migrĂ© 3073 packages directement dans ProjectFv1/Content pendant que l'Ă©diteur de ProjectFv1 Ă©tait ouvert (preuve : Project_F/Saved/Logs/Project_F.log, lignes LogSavePackage: Moving ... to E:/projet/ProjectFv1/Content/...). â ïž Ne jamais migrer vers ce projet avec son Ă©diteur ouvert.
DĂ©gĂąts constatĂ©s : 1449 assets suivis par git de Characters/UEFN_Mannequin/ Ă©crasĂ©s (animations + chooser tables, liĂ©es dĂ©sormais aux notifies/enums de Content/Blueprints/), 782 fichiers Systems/Weather/UltraDynamicSky/ Ă©crasĂ©s (widgets mĂ©tĂ©o sans leurs structs ST_Weather* â 149 erreurs), Content/Blueprints/ recréé comme copie complĂšte (137 vrais assets) du framework de Systems/Blueprints/. Les enums/structs des deux copies DIVERGENT (ex. E_MovementDirection : F/B/LL/LR/RL/RR vs Forward/Back/left/âŠ, E_Gait sans Prone/Swimming) : ne JAMAIS les fusionner aveuglĂ©ment.
Réparation (décisions utilisateur) :
- Météo : les 782 fichiers UltraDynamicSky restaurés depuis le commit
d29748b(LFS). Versions migrées sauvegardées dansE:\projet\ProjectFv1_backup_migration_2026-09-13\. - Anims/choosers migrés conservés. Contexte (
ContextData) des 7 chooser tables CMC/traversal remis aux valeurs du commit :CHT_PoseSearchDatabases(+_Dense/_Sparse/_ExtremeSparse)etCHT_CMCCharacterAnimationsâSystems/Blueprints/SandboxCharacter_CMC_ABP(+S_ChooserOutputsSystems) ;CHT_TraversalMontages_CMC/_MoverâSystems/Blueprints/Data/S_TraversalChooserInputs/Outputs. Lignes Bow du chooser Dense perdues (voir §1.3). - Structs strictement identiques fusionnĂ©es (
consolidate_assets, redirecteurs laissĂ©s) :Content/Blueprints/Data/S_CHT_TraversalMontages_IN/OUTâSystems/.../S_TraversalChooserInputs/Outputs,Content/Blueprints/Data/S_ChooserOutputsâSystems/.../S_ChooserOutputs. Pins deContent/Blueprints/AC_TraversalLogic(traversal du Mover) rebranchĂ©es. - Doublon GASP du personnage CMC supprimĂ© :
Content/Blueprints/SandboxCharacter_CMC+_ABP. RĂ©fĂ©rences de dĂ©mo redirigĂ©es vers/Game/SandboxCharacter_CMC(depuis dĂ©placĂ© dans/Game/Core/Character/) / l'ABP Systems (PC_Sandbox.Characters,AC_PreCMCTick,GM_Sandbox.PawnClasses_Soft,EUW_PawnOverrideButton.Object, variable locale deBP_NotifyState_EarlyTransition). (Content/Widgets/a Ă©tĂ© supprimĂ© le 2026-09-14.) STT_PlayAnimFromBestCost(Systems) pointe dĂ©sormais versSystems/Blueprints/SmartObjects/AC_SmartObjectAnimation.Config/DefaultGameplayTags.ini: ajout des tags du sampleFoley.Event.*etSmartObject.ObjectType.Player/Bench(manquants â avertissements massifs + StateTree SmartObject non liable).
Contenu du framework du sample conservé volontairement (déplacé le 2026-09-14, voir §4.2.1 et « Convergence partielle » ci-dessous) :
Systems/Aiming/(ABP_AimingMaster,ABP_AimingMaster_UEFN,CH_AO,CH_Base_AO_Animechooser) â systĂšme de visĂ©e/aim offset dĂ©veloppĂ© dansProject_F, utilisĂ© parSandboxCharacter_Mover_ABP.Systems/Mover/SandboxCharacter_Mover/_ABP/_Ragdollâ personnage alternatif plugin Mover (+Systems/Mover/GM_Sandbox/PC_Sandbox;dev_mapde dĂ©mo supprimĂ© le 2026-09-14).- le reste du framework dupliquĂ©, dans
Systems/Mover/(AC_TraversalLogic, BPI_*, Data/, Cameras/âŠ) ; ses notifies restent dansContent/Blueprints/AnimNotifies/(liĂ©s Ă 1278 animations). Chooser tables toujours liĂ©es Ă ce framework :CHT_PoseSearchDatabases_Relaxed,CHT_MoverCharacterAnimations_PoseMatch,CHT_GetUpMontages,CHT_CharacterInteractionPSDs.
Convergence partielle (2026-09-14) :
- Enums fusionnés : les 17 enums du sample de
Content/Blueprints/Data|Cameras|AnimNotifies/(E_Gait,E_Stance,E_MovementMode,E_MovementState,E_MovementDirection,E_MovementDirectionBias,E_RotationMode,E_AnalogStickBehavior,E_ExperimentalStateMachineState,E_RagdollInjuryState,E_TraversalActionType,E_CameraMode,E_CameraStyle,E_EarlyTransition_Condition,E_EarlyTransition_Destination,E_FoleyEventSide,E_TraversalBlendOutCondition) ont été fusionnés dans leurs jumeaux deSystems/Blueprints/(17 redirecteurs laissés à l'ancien emplacement). Valeurs propres au sample ajoutées en fin d'enum cÎté projet (voir §4.2) et pins/switchs de la chaßne Mover remappés dessus. Interfaces et structs Systems enrichies en conséquence (§4.2). - Réparations consécutives (piÚge décrit en §9) : variables d'enum vidées retypées et liens rebranchés dans
SandboxCharacter_Mover,SandboxCharacter_Mover_Ragdoll,SandboxCharacter_Mover_ABP(restaurĂ© depuis sauvegarde puis remappĂ©),BP_AnimNotify_TriggerRagdoll,AnimNotifies/BP_NotifyState_EarlyTransitionetBP_NotifyState_MontageBlendOut(liens comparĂ©s un Ă un Ă leurs jumeaux Systems). Chaque asset validĂ© par rechargement de son package. - ArrĂȘt de la convergence (dĂ©cision utilisateur) : Ă cause de ce piĂšge, le reste de
Content/Blueprints/(Mover, Aiming, AC/BPI/structs/notifies/caméras du sample) n'est PAS fusionné. Il a été seulement déplacé, sans fusion, le 2026-09-14 (voir §4.2.1) ; les doublons restants sont une dette connue.
Restauration Motion Matching (2026-09-14, dĂ©cision utilisateur) : un audit des 189 donnĂ©es Motion Matching modifiĂ©es depuis d29748b (comparaison des rĂ©fĂ©rences /Game/... des blobs git avant/aprĂšs) a trouvĂ© 7 assets dĂ©gradĂ©s par la migration, tous restaurĂ©s depuis d29748b (toutes leurs rĂ©fĂ©rences existent encore) : CHT_PoseSearchDatabases_Dense (19 bases perdues : Bow, Prone, nage, cover accroupi, Push ; colonnes E_CoverD/Weapon_Equip), Channels/PSC_Traversal_Head et _Pos (pointaient sur la BPI du sample au lieu de Systems/Blueprints/BPI_SandboxCharacter_ABP), Schemas/PSS_Default et PSS_Idle (table miroir Rigs/MDT_UEFN_Mannequin perdue), Normalization_Sets/PSN_Relaxed_All (le Mover y perd PSD_SM_Mover_TraversalTransitions), Databases/Dense/PSD_Dense_Stand_Idles (mesh d'aperçu). Seul autre Ă©cart trouvĂ©, conservĂ© : Traversal/CHT_TraversalMontages_Mover (montages Climb Relaxed â Neutral, chooser du Mover).
Ătat vĂ©rifiĂ© en fin de rĂ©paration : passe de compilation complĂšte, 435 Blueprints, 0 erreur (non encore testĂ© en PIE). Dettes connues non liĂ©es Ă la migration : tags Attachments.* (§2.1), animations AGIS sans squelette (voir §9 : Systems/Inventory/Other/Animations/DeathAnim_AGIS et Rifle/* â compatibles Ă 100 % avec SK_UEFN_Mannequin, Ă assigner Ă la main dans l'Ă©diteur ; Jog/, WALK/, TurnInPlace/, AIM_Rifle_Idle_ADS inutilisĂ©es et incompatibles), « Unknown structure » au chargement de Systems/Blueprints/BPI_SandboxCharacter_Pawn (antĂ©rieur au 2026-09-07).
9. Notes pour les IA : piĂšges connus de l'outillage
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
.uassetgardent 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, mettrespline_has_been_edited = Truesinon 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 Choosersans objet de contexte branchĂ© renvoie TOUJOURS une liste vide (2026-09-18) : constatĂ© surSandboxCharacter_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,ValidDatabasesrestait 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 brancherself(type id crĂ©able :Variables|Getareferencetoself). SymptĂŽme jumeau Ă surveiller : un chooser dupliquĂ© dont on a changĂ© leContextDatafonctionne, 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 sonInheritableComponentHandler) le prend comme archĂ©type et sa sauvegarde Ă©choue avecIllegal reference to private object. PrĂ©fĂ©rer un enregistrement Ă l'exĂ©cution (MoverComponent::AddMovementModeFromClassau BeginPlay) ou l'Ă©dition manuelle dans l'Ă©diteur. -
PIĂGE â
SubobjectDataSubsystem.rename_subobjectjuste aprĂšsBlueprintService.remove_componentprovoque 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 (0xC0000005au 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Ă© parBlueprintService.add_component(..., parent_name="Capsule")reçoit unParentComponentOrVariableNameexplicite qui dĂ©clenche l'avertissementReparenting 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,
ValidDatabasesvide) puis correcte Ă l'appel suivant. Toujours relire dans un second appel avant de conclure Ă un bug. De plus,BlueprintService.list_graphs/list_variablesrenvoient 0 Ă©lĂ©ment pendant une session PIE : arrĂȘter le PIE avant d'inspecter un graphe. -
build_graphattend un champ"ref"pour identifier chaque nĆud dans la listenodes(pas"id"). Un mauvais nom de champ Ă©choue silencieusement (retourneNonesans erreur explicite). -
Les variables locales à une fonction (paramÚtres, locals créés via
add_object_variableavecgraph=...) ne sont pas fiables avecbuild_graph'svariable_get/variable_set: préférer des variables membres du Blueprint. -
Un
K2Node_VariableSet/Getcréé 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 surWB_Containeret sur un widget créé cette session) â toujours vĂ©rifier les pins du nĆud créé (get_node_pins) avant de cĂąbler, ou utiliserbuild_graphavectype: "variable_set"+params.variableen contexte "self" qui est fiable. -
Appeler une fonction Blueprint préexistante (créée dans une session antérieure/par le plugin marketplace) sur un autre Blueprint peut échouer silencieusement selon la méthode utilisée. Privilégier l'accÚs direct aux propriétés (
member_get, fiable) plutÎt que l'appel de fonction cross-Blueprint quand c'est possible ; sinon testeradd_function_call_on_variableet vérifier le résultat viaget_node_pins/get_nodes_in_graph. -
Ăcrire une valeur littĂ©rale sur un pin de type
Text,ObjectouClassviaset_node_pin_valueĂ©choue souvent silencieusement Ă l'affichage (get_node_pinsrenvoie toujoursdefault_value: "") mĂȘme quand l'assignation a rĂ©ellement fonctionnĂ© â vĂ©rifier via une compilation (erreurs de compilation manquantes = probablement OK) plutĂŽt que via une relecture du pin. -
Toujours compiler ET sauvegarder un Blueprint aprĂšs modification (
BlueprintEditorLibrary.compile_blueprint+EditorAssetLibrary.save_loaded_asset), puis tester en PIE et lire les logs (EditorToolset.LogsToolset.GetLogEntries, filtrer sur"Blueprint Runtime Error") pour détecter les erreurs à l'exécution qu'une compilation réussie ne révÚle pas (ex. accÚs à un élément de tableau hors limites). -
Le clavier cible du jeu est AZERTY : vérifier les mappings de touches existants (
IMC_Sandbox,IMC_AGIS_Character,IMC_AGIS_InventoryTab) avant d'assigner une nouvelle touche, et choisir des touches physiquement identiques entre QWERTY/AZERTY.
PiÚges du toolset editor_toolset.toolsets.blueprint.BlueprintTools (create_node/connect_pins/write_graph_dsl/get_node_infos, utilisé depuis le systÚme d'armes du 2026-09-05) :
-
La DSL
write_graph_dslcasse sur untype_idcontenant une parenthĂšse fermante suivie d'autres caractĂšres (ex.BOTH|GetItem(copy)ByUIDĂ©choue avec "does not exist" car le tokenizer coupe au premier)) ; untype_idse terminant PAR une parenthĂšse fonctionne (Utilities|Array|Get(acopy)). Dans ce cas, construire le nĆud Ă la main (create_node/connect_pins) plutĂŽt que via la DSL. -
Un
type_idretournĂ© parfind_node_types(ex.Variables|Default|GetACWeapon) peut diffĂ©rer dutype_idaffichĂ© ensuite parget_node_infospour CE nĆud (ex.|GetAC_Weapon, avec underscore) : toujours utiliser la chaĂźne defind_node_typespour crĂ©er/rĂ©fĂ©rencer un nĆud dans la DSL, jamais celle affichĂ©e aprĂšs coup parget_node_infos. -
Ăditer une propriĂ©tĂ© d'un composant SCS hĂ©ritĂ© (ex. changer le mesh d'un
StaticMeshComponentdéfini dans une classe parente, depuis le Blueprint enfant) :SubobjectDataBlueprintFunctionLibrary.get_object/get_associated_objectrenvoient le template du PARENT (le modifier casse le parent pour toutes ses classes filles !). Utiliserget_object_for_blueprint(data, child_blueprint)qui crée correctement l'override propre à l'enfant. -
Itérer un
Array[SubobjectDataHandle]avecfor h in handles:casseget_data/get_variable_name(erreur de nativisation) ; indexer explicitement (for i in range(len(handles)): h = handles[i]) fonctionne. -
Un Blueprint Function Library (BFL) se crée avec
unreal.BlueprintFunctionLibraryFactory()(pas leBlueprintFactorygénérique +parent_class, qui échoue avec "Cannot create a blueprint based on the class"). -
Depuis
execute_python_code, appeler une fonction Blueprint sur une instance PIE viaactor.call_method(...)nĂ©cessite le nom d'affichage exact avec ses espaces (ex."Set Item Actor Owner","Primary Use"), pas une version condensĂ©e/snake_case â sauf pour certains getters de variable auto-gĂ©nĂ©rĂ©s dont le nom interne rĂ©el ne correspond ni Ă l'un ni Ă l'autre (Ă vĂ©rifier au cas par cas). -
Créer un
InputActionen Python :unreal.InputAction_Factory()(PASunreal.InputActionFactory, qui n'existe pas) +AssetToolsHelpers.get_asset_tools().create_asset(...). Pour mapper une touche dans unInputMappingContextexistant, préférerunreal.InputService.add_key_mapping(imc_path, ia_path, "F9")(service VibeUE dédié) plutÎt que d'éditer la propriété dépréciéemappingsde l'IMC directement en Python. -
Construire un widget UMG en Python :
unreal.WidgetService.add_component/set_property/bind_eventfonctionnent bien pour la hiĂ©rarchie et les propriĂ©tĂ©s, mais il n'existe aucununreal.WidgetBlueprintLibrary.create_widgetexposĂ© pour instancier un widget Ă la volĂ©e. Pour un test rapide en PIE, utiliserunreal.WidgetService.spawn_widget_in_pie(chemin)(retourne un handle qu'on repasse Ăremove_widget_from_pie) â mais ce handle n'expose pas d'appel de fonction arbitraire sur l'instance ; il ne sert qu'Ă l'afficher/la retirer et lire ses propriĂ©tĂ©s (get_live_property). -
EditorToolset.EditorAppToolset.CaptureAssetImage/CaptureViewportsont le seul moyen fiable de voir un rĂ©sultat (mesh, matĂ©riau, scĂšne) : le retour JSON est trop volumineux pour ĂȘtre lu tel quel (limite de tokens) â toujours passer par un script Python (base64.b64decodedu champreturnValue.data, Ă©crit dans le scratchpad) puisReadsur le PNG obtenu. -
Un asset
.uassetpeut se retrouver corrompu Ă vide (0 vertex/triangle, bounds nuls) aprĂšs une fermeture anormale de l'Ă©diteur (coupure de courant, crash) sans que sa taille de fichier ni son chargement ne signalent d'erreur â toujours vĂ©rifierget_num_vertices(0)/get_bounds()(StaticMesh) aprĂšs un redĂ©marrage suspect avant de chercher un autre bug.delete_asset/consolidate_assetspeuvent Ă©chouer silencieusement (retourFalse, sans exception) sur un tel asset corrompu mĂȘme sans rĂ©fĂ©renceur restant â dans ce cas, renommer le nouvel asset importĂ© sous un autre nom plutĂŽt que de s'acharner Ă rĂ©utiliser le chemin d'origine. -
Toute variable membre booléenne (
bXxx) affiche son nom SANS le prĂ©fixebdans les nĆuds Get/Set gĂ©nĂ©rĂ©s par la DSL (GetCanSeePlayer, pasGetbCanSeePlayer) â mais son nom de propriĂ©tĂ© brut, tel qu'attendu parget_editor_property/set_editor_propertyen Python ET parStateTreeService.bind_*_property_to_context(chemins de contexte), conserve le prĂ©fixeb("bCanSeePlayer","AnimalSenses.bScentDetected"). Utiliser le nom sansbdans l'un de ces deux contextes Ă©choue silencieusement en DSL (nĆud introuvable) ou avec "Malformed target property path" cĂŽtĂ© StateTree. -
delete_nodesur un nĆud dont une pin est encore rĂ©fĂ©rencĂ©e par un AUTRE nĆud (ex. un nĆudSelf/GetXxxpur, rĂ©utilisĂ© par plusieurs consommateurs) peut laisser une connexion fantĂŽme cĂŽtĂ© survivant :get_node_infoscontinue de lister une pin connectĂ©e vers le node supprimĂ© (qui n'apparaĂźt plus dansfind_nodes), et la compilation Ă©choue avec l'erreur gĂ©nĂ©riqueInternal compiler error inside CreateExecutionSchedulesans dĂ©signer le nĆud fautif. Diagnostic : dumperget_node_infosde TOUS les nĆuds du graphe et chercher une pin connectĂ©e vers un node absent defind_nodes; le node fantĂŽme existe encore assez longtemps en mĂ©moire (non garbage-collectĂ©) pour quebreak_pinsfonctionne dessus malgrĂ© tout â l'appeler explicitement sur cette connexion rĂšgle l'erreur. -
Une UserDefinedEnum (créée via
unreal.EnumStructService.create_enum) ne peut PAS servir de type Ă une variable membre, un paramĂštre de fonction ou un paramĂštre de dispatcher via les outils disponibles (add_variable/add_function_paramn'acceptent que bool/int/float/byte/name/string/text/Vector/Rotator/Transform/Vector2D/LinearColor) â limitation dĂ©jĂ notĂ©e pourAC_Stats::OnDamaged, reconfirmĂ©e pourE_AnimalState. Contournement : stocker enbyteet convertir Ă l'affichage seulement si besoin (Utilities|String|ToString(Byte)). -
Une StateTree Task Blueprint (
StateTreeTaskBlueprintBase) ne tique QUE si sa CDO ashould_call_tick_only_on_events = trueâ malgrĂ© son nom qui suggĂšre l'inverse ("seulement sur Ă©vĂ©nements"), c'est en rĂ©alitĂ© l'interrupteur gĂ©nĂ©ral qui activeReceiveLatentTick. Aucune propertybShouldCallTickdistincte n'est exposĂ©e. -
Chaßner plus de deux concaténations
(+ a b)de String dans une mĂȘme expression DSL imbriquĂ©e casse avecCould not connect pin ReturnValue to A(constatĂ© surBP_AnimalBase::DebugTick) â mĂȘme en sĂ©parant chaque Ă©tape par unbindintermĂ©diaire. Contournement : limiter chaque nĆud+Ă DEUX opĂ©randes littĂ©raux/variables simples, et multiplier les appelsDrawDebugString/lignes plutĂŽt que de construire une seule chaĂźne longue. -
Une donnĂ©e cross-instance (lire la variable d'un AUTRE acteur de mĂȘme classe, ex. le
HerdIDd'un autreBP_AnimalBasependantBroadcastAlertToHerd) n'est PAS accessible via le getterVariables|Default|GetXxxgĂ©nĂ©rĂ© par la DSL (celui-ci n'a pas de pinself/cible, contrairement aux nĆudsClass|MaClasse|MaFonctionqui, eux, exposent bien unselfsubstituable). 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 (voirReceiveHerdAlert(ThreatLocation, CallerHerdID)). -
Une nouvelle StateTree (
unreal.StateTreeService.create_state_tree) dĂ©marre SANS aucun Ă©tat racine :add_state(path, "Root", ...)Ă©choue silencieusement (retourneFalse) tant qu'un premieradd_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) viaK2Node_CreateDelegate.set_create_delegate_functioncompile sans erreur immĂ©diate mais casse la compilation Ă la volĂ©e suivante avecInternal compiler error inside CreateExecutionScheduleâ et peut mĂȘme faire apparaĂźtre des nĆudsAddEventparasites (EventTick, EventActorBeginOverlapâŠ) ailleurs dans le graphe. Un dispatcher avec paramĂštres doit ĂȘtre liĂ© Ă un Custom Event (add_eventavec un nom arbitraire crĂ©e un vraiK2Node_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, retourneNoneet laisse le graphe inchangĂ© ou VIDE ; le vrai message n'apparaĂźt que dansSaved/Logs/ProjectFv1.log(LogScript: Warning: AssertionError: The node could not be created / ⊠does not existouRuntimeError: Could not connect pin âŠ). Toujours vĂ©rifier chaque Ă©criture parread_graph_dsl(chercher un nĆud attendu) avant de sauvegarder. PiĂšges constatĂ©s : (a)Math|Byte|Equal(Byte)etMath|Vector|vector+vectorsont RELUS parread_graph_dslmais REFUSĂS Ă l'Ă©criture â utiliser les opĂ©rateurs==/+; (b) les appels de fonction du Blueprint lui-mĂȘme (CallFunction|MaFonction) ont une pinselfen premiĂšre position : passer les arguments par mot-clĂ© (:Anim x :Loop true), sinon le premier argument est branchĂ© surself; (c) les getters de variables Ă underscore perdent l'underscore dans le type_id (Anim_IdleâVariables|Default|GetAnimIdle), etfind_node_typesrenvoie aussiCallFunction|ApplyIdleforStateavec la casse de l'affichage ; (d)read_graph_dslaffiche parfois un nĆud sous une catĂ©gorie trompeuse (CustomizableObjectInstance|SetCurrentStatepour un appel ĂBP_AnimalBase::SetCurrentState) â vĂ©rifier avecget_node_infosavant de conclure Ă un mauvais binding ; (e)BlueprintTools.create_nodeattend ununreal.IntPointpourpos, pas unVector2D. -
(2026-09-14) StateTree : une tĂąche Blueprint qui appelle
FinishTaskdansEnterStatetermine l'Ă©tat dans la mĂȘme frame (TasksCompletion=Any), etStateTreeService.set_task_considered_for_completion(..., False)renvoieTruemais n'a PAS empĂȘchĂ© ce comportement en PIE (UE 5.8). Pour une tĂąche « fire and forget » (ex.STT_SetAnimalState), ne PAS appelerFinishTask. Diagnostic :log LogStateTree Verboseen PIE puis compter lesEnter statedans le log. -
(2026-09-14) StateTree : une transition posée sur
Root(triggerOnTick) 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 == falsepourRootâFlee). -
Un NavMeshBoundsVolume ajouté par script (
SceneTools.add_to_scene_from_class) ne gĂ©nĂšre PAS automatiquement de NavMesh : leRecastNavMesh-Defaultcorrespondant naĂźt avecRuntimeGeneration = 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)PUISunreal.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_dslinsĂš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Ă©elleLContainers'affiche(|GetL_Container), PAS(|GetLContainer)â idemLItemNameâ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 viafind_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_propertyen 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_assetrenvoieFalsesans exception) tant que le PIE n'est pas arrĂȘtĂ© â toujoursStopPIEavant de sauvegarder un asset qu'une session PIE utilise, et re-tenter la sauvegarde aprĂšs l'arrĂȘt. -
CORROLAIRE DANGEREUX : aprÚs tout échec de
save_loaded_assetdĂ» au PIE, StopPIE PUIS ressauvegarder IMMĂDIATEMENT, et toujours revĂ©rifier viaread_graph_dsl/find_nodesaprĂšs un redĂ©marrage/arrĂȘt du PIE qu'une Ă©dition rĂ©cente est bien encore prĂ©sente avant de continuer Ă construire dessus â une Ă©dition compilĂ©e avec succĂšs pendant que le PIE tournait peut sembler perdue Ă la prochaine lecture si la sauvegarde qui a suivi a Ă©chouĂ© silencieusement. -
PIĂGE MAJEUR â graphe d'implĂ©mentation d'interface Blueprint fragile et auto-rĂ©gĂ©nĂ©rĂ© (2026-09-06) : le graphe qui implĂ©mente une fonction de Blueprint Interface (ex.
BP_Item_HoldableBase:On Item Attached, implĂ©mentantBPI_HoldableItem::On Item Attached) peut revenir tout seul Ă son Ă©tat d'origine aprĂšs une compilation ultĂ©rieure â de N'IMPORTE QUEL Blueprint de la hiĂ©rarchie, pas seulement celui qu'on Ă©dite â mĂȘme quandread_graph_dslavait confirmĂ© l'Ă©dition juste aprĂšs une sauvegarde rĂ©ussie (save_loaded_assetâTrue, mtime du.uassetĂ jour). Unreload_packagesforcĂ© depuis Python confirme que c'est bien le contenu SUR DISQUE qui a rĂ©gressĂ©, pas juste l'Ă©tat en mĂ©moire â la persistance de ce type de graphe est donc bien plus fragile qu'une fonction normale. Reproduit 3 fois de suite sur le mĂȘme graphe dans cette session malgrĂ© des re-sauvegardes systĂ©matiques. Ne JAMAIS hĂ©berger de logique mĂ©tier propre (dispatcher broadcast, etc.) directement dans un graphe d'implĂ©mentation d'interface â s'en servir seulement comme passe-plat trivial si besoin, ou mieux : contourner entiĂšrement l'interface et appeler la fonction/le dispatcher cible directement depuis l'appelant via unCastexplicite vers la classe concrĂšte (ex.Inventory_Equipper::AttachItemToOwnercasteItemenBP_Item_HoldableBaseet appelleCallOnHeldStateChangeddirectement, sans jamais passer par l'interface) â cette approche s'est rĂ©vĂ©lĂ©e stable aprĂšs le contournement. -
Référence d'interface
K2Node_Message/K2Node_CallFunctioncorrompue aprĂšs un renommage d'interface (2026-09-06) : un appel d'interface existant peut afficher untype_id/catĂ©gorie qui ne correspond Ă AUCUN asset actuel du projet (ex.BPIEquippableItem|OnItemAttachedalors que seuleBPI_HoldableItemexiste â probablement un renommageBPI_EquippableItemâBPI_HoldableItemfait avant cette session) tout en compilant sans erreur et en affichant des types de pins statiquement cohĂ©rents (get_node_type_pinsmontrait bienself: BPI Holdable Item Interface) â la compilation rĂ©ussit car un systĂšme de redirection (CoreRedirects ou Ă©quivalent) fait correspondre le nom au niveau des TYPES, mais l'appel ne dĂ©clenche RIEN Ă l'exĂ©cution (confirmĂ© par prints de debug ne s'affichant jamais cĂŽtĂ© rĂ©cepteur, malgrĂ© la classe cible confirmĂ©e implĂ©menter l'interface viaunreal.SystemLibrary.does_class_implement_interface). Un nĆud fraĂźchement créé avec le MĂMEtype_idpeut mĂȘme se rĂ©soudre en un type de nĆud DIFFĂRENT (K2Node_CallFunctionau lieu duK2Node_Messaged'origine) â signe supplĂ©mentaire d'une rĂ©fĂ©rence historique corrompue plutĂŽt que d'un vrai type_id valide. Diagnostic : ajouter un print cĂŽtĂ© rĂ©cepteur et vĂ©rifier empiriquement qu'il se dĂ©clenche ; si l'appelant confirme passer par le nĆud (print juste avant) mais que le rĂ©cepteur reste silencieux, suspecter ce piĂšge. Fix : ne pas rĂ©utiliser l'ancien nĆud ni recrĂ©er un nĆud du mĂȘmetype_idâ contourner l'interface entiĂšrement (voir point ci-dessus). -
Consommer un stock d'inventaire PASSIF (jamais équipé/lùché) ne doit jamais passer par un acteur monde (2026-09-06) : la macro
ML_InventoryMacros::Get Item Actor(et donc tout appelUtilities|GetItemActor) retourne TOUJOURS invalide pour un item empilĂ© qui n'a jamais Ă©tĂ© spawnĂ© comme acteur (ex. un stack de flĂšches "Arrow" qui reste en inventaire, jamais Ă©quipĂ©) â ce n'est pas un bug ponctuel, c'est le comportement normal : ces items n'ont simplement pas d'acteur tant qu'ils ne sont pas Ă©quipĂ©s/lĂąchĂ©s dans le monde. Une fonction du typeConsumeArrow/ReduceAmmoqui suit le patronFindItem â GetItemActor â SERVER|ReduceAmount(item_actor, ...)Ă©choue donc silencieusement (retourne false) pour ce genre d'item, mĂȘme quandFindItema bien trouvĂ© le stack. Fix correct : opĂ©rer directement sur les DONNĂES via l'adresse de l'item, avecInventory__Main::AddItemAmount(ItemAddress, DeltaAmount)(nĂ©gatif pour consommer) â une fonction RPC serveur qui gĂšre nativement le retrait de l'array si le montant tombe Ă 0, sans jamais nĂ©cessiter d'acteur. Le mĂ©canismeGetItemActor+fonction-sur-acteur reste correct UNIQUEMENT pour des items dont l'acteur est garanti d'exister (ex. un chargeur d'arme Ă©quipĂ©, actif commeMagazine Reference). -
PIĂGE CRITIQUE â brancher UNE sortie de pose sur PLUSIEURS entrĂ©es dans un
AnimGraphcasse toute la locomotion (2026-09-06) : contrairement Ă un graphe Blueprint normal, une sortiePose Link(AnimGraphNode_*) qui alimente directement 2+ entrĂ©es fait ĂVALUER EN DOUBLE, Ă chaque frame, TOUT le sous-graphe en amont â pas seulement recalculer une valeur, mais rĂ©ellement re-tick les nĆuds AVEC ĂTAT (State Machine, Motion Matching, Blend Space avec accumulation de temps, Inertialization) une deuxiĂšme fois. SymptĂŽme observĂ© : le personnage "bouge de façon bizarre" (mouvement erratique/saccadĂ©) dĂšs qu'un nĆud en amont d'un fan-out a un Ă©tat interne dĂ©pendant du temps â la Motion Matching et les State Machines de ce projet en amont deSlot 'DefaultSlot'Ă©taient tickĂ©es deux fois par frame aprĂšs l'ajout (sans prĂ©caution) d'un second consommateur sur la sortie de ce Slot. Fix obligatoire : ne jamais connecter directement une sortie de pose partagĂ©e Ă plusieurs entrĂ©es â insĂ©rer unSave Cached Pose 'NomUnique'juste aprĂšs la source, puis unUse Cached Pose 'NomUnique'par consommateur (le projet utilise dĂ©jĂ ce patron ailleurs dansSandboxCharacter_CMC_ABP, ex. cacheMotionMachinconsommĂ© parMirror_0ETBlendListByBool_3â repĂ©rable viafind_nodes/get_node_infosavant de dupliquer une sortie, pour voir si le patron existe dĂ©jĂ ). Une rĂ©gression de ce type NE PROVOQUE AUCUNE ERREUR DE COMPILATION â le graphe compile et sauvegarde sans avertissement, le bug n'est visible qu'en jouant. -
CrĂ©er un nĆud de Get/Set VARIABLE d'une AUTRE classe (pas une fonction) via
create_node(2026-09-06) :find_node_typesaveccontext_pinspointant vers une pin dĂ©jĂ castĂ©e Ă la classe cible retourne bien le type_id correct (ex.Variables|Default|SetWeapon), mais ce type_id Ă©choue Ă la crĂ©ation viacreate_node(does not exist) MĂME avecdeclaring_classrenseignĂ© âdeclaring_classne sert qu'Ă dĂ©sambiguĂŻser un type_id dĂ©jĂ trouvĂ©, pas Ă Ă©largir la recherche. Fix : rappelerfind_node_typesaveccontext_pins: [](SANS contexte) sur le mĂȘme filtre â la forme SANS contexte rĂ©vĂšle le type_id RĂELLEMENT crĂ©able, qui suit la conventionClass|<NomClasseSansUnderscore>|<NomPropriĂ©tĂ©>(ex.Class|SandboxCharacterCMC|SetWeapon), diffĂ©rent de la formeVariables|Default|...que le contexte affichait. Une fois créé, le nĆud peut ensuite s'afficher avec un LABEL DSL trompeur (catĂ©gorieSandboxCharacterCMCABPau lieu deSandboxCharacterCMCpar ex.) â vĂ©rifier le type rĂ©el de la pinselfviaget_node_infos(pas la catĂ©gorie DSL) pour confirmer la bonne classe cible. -
Configurer un nĆud
AnimGraphNode_*(Slot, LayeredBoneBlend, etc.) au-delĂ de ses pins (2026-09-06) : le nom d'unSlot(SlotName) et les filtres de branche d'unLayered Blend Per Bone(LayerSetup[i].BranchFilters) ne sont PAS des pins â ce sont des propriĂ©tĂ©s du sous-structNode(leFAnimNode_*runtime) portĂ© par leAnimGraphNode_*. Invisibles viaget_node_infos/create_node/set_pin_value. AccĂšs uniquement via Python :node.get_editor_property("Node")renvoie le struct runtime, dont les champs se lisent/Ă©crivent avecget_editor_property/set_editor_propertyen snake_case (slot_name,layer_setup,blend_weights...) â mais pour un ARRAY de structs imbriquĂ©s (ex.layer_setup: [InputBlendPose], chaqueInputBlendPose.branch_filters: [BranchFilter]), modifier un Ă©lĂ©ment en place ne suffit pas : construire les structs indĂ©pendamment (unreal.BranchFilter(),unreal.InputBlendPose()), les remplir viaset_editor_property, PUIS rĂ©assigner le tableau complet sur le struct parent (ibp.set_editor_property("branch_filters", [bf]), puisnode_struct.set_editor_property("layer_setup", [ibp]), puisnode.set_editor_property("Node", node_struct)) â une mutation in-place sans cette rĂ©assignation finale ne persiste pas.to_dict()sur ces structs renvoie souvent{}de façon trompeuse mĂȘme quand les propriĂ©tĂ©s sont bien accessibles individuellement viaget_editor_propertyâ ne pas se fier Ăto_dict()pour vĂ©rifier un struct AnimGraph, toujours relire chaque propriĂ©tĂ© nommĂ©ment. -
Le cache de découverte de
find_node_typespour un AUTRE Blueprint rĂ©fĂ©rençant fraĂźchement une fonction ajoutĂ©e ailleurs (ex.Class|InventoryPlayer|MaNouvelleFonctioncherchĂ© depuis un Widget qui possĂšde une variable de typeInventory_Player) peut rester pĂ©rimĂ© et ne rien retourner mĂȘme aprĂšs compilation+sauvegarde de la classe modifiĂ©e âcreate_nodeavec letype_iddĂ©duit par convention (Class|<NomClasseSansUnderscore>|<NomFonction>) fonctionne quand mĂȘme ; ne pas conclure Ă une impossibilitĂ© sur la seule base d'unfind_node_typesvide. -
unreal.get_editor_subsystem(unreal.EditorActorSubsystem).get_all_level_actors()(et plus gĂ©nĂ©ralement les APIsEditorActorSubsystem) redevient silencieusement vide pendant qu'une session PIE est active â ces APIs ciblent le monde Ă©diteur, pas le monde PIE. Pour inspecter/piloter des acteurs PENDANT une session PIE (vĂ©rifier qu'une IA se dĂ©place, lire une variable en temps rĂ©el), utilisereditor_toolset.toolsets.scene.SceneTools.find_actors(qui rĂ©sout correctement vers le mondeUEDPIE_0_<NomNiveau>) puisunreal.load_object(None, refPath)sur le chemin PIE retournĂ©. -
write_graph_dsl(réécriture complĂšte d'un graphe) casse sur 2 instances DIFFĂREMMENT TYPĂES d'un mĂȘme nĆud wildcard enum (2026-09-06) :Utilities|Enum|NotEqual(Enum)/Equal(Enum)sont des nĆuds gĂ©nĂ©riques dont le type se fixe au premier pin connectĂ© â un graphe EXISTANT peut trĂšs bien contenir plusieurs instances typĂ©es diffĂ©remment (constatĂ© surGet_MMInterruptMode: 3ĂNotEqual(Enum)+ 2ĂEqual(Enum), typesE_MovementMode/E_MovementState/E_GaitmĂ©langĂ©s, qui coexistent sans problĂšme). Mais reconstruire ce mĂȘme graphe en un seul appelwrite_graph_dslen y ajoutant une NOUVELLE instance sur un type enum diffĂ©rent (ex.Weapon_Equip) Ă©choue systĂ©matiquement avecCould not connect pin ReturnValue to B, quel que soit l'ordre des clauses â le compilateur DSL semble partager le typage wildcard entre toutes les instances créées dans une mĂȘme passe, contrairement au graphe dĂ©jĂ compilĂ© oĂč chaque instance est indĂ©pendante. Heureusement l'Ă©chec est bien transactionnel (read_graph_dslconfirme le graphe intact aprĂšs l'erreur, aucun Ă©tat partiel). Fix : ne PAS passer par une réécriture DSL complĂšte pour ce genre d'ajout â construire les nĆuds un par un (create_nodepour les 2Variables|Default|GetXxx+ le nouveauNotEqual(Enum),connect_pinspour les typer), puis brancher le rĂ©sultat sur le nĆud logique existant. Un nĆudMath|Boolean|ORBoolean/ANDBoolean(K2Node_CommutativeAssociativeBinaryOperator) accepte nativement un pin de PLUS viaadd_node_pin(retourne le nouveauPinID, ex.CaprĂšsA/B) â pas besoin de recrĂ©er tout l'arbre logique, juste ajouter le pin et y connecter la nouvelle condition.read_graph_dsln'affiche ensuite QUE les 2 premiers pins d'unor/andĂ 3+ entrĂ©es (limite d'affichage du lecteur DSL) â vĂ©rifier un ajout de ce type viaget_node_infossur le nĆud lui-mĂȘme, pas via une relecture DSL qui semblerait ignorer l'Ă©dition. -
Architecture Motion Matching â pourquoi une nouvelle base de donnĂ©es "valide" peut ĂȘtre ignorĂ©e indĂ©finiment (2026-09-06) :
Update_MotionMatching(fonction ABP thread-safe, tourne chaque frame) faitEvaluateChooser â SetValidDatabases â MotionMatchingAnimNodeLibrary.SetDatabasesToSearch(node, databases, InterruptMode)â le 3á” paramĂštre (Get_MMInterruptMode, une fonction sĂ©parĂ©e) contrĂŽle si le nĆudAnimGraphNode_MotionMatchinga le DROIT de remettre en cause la pose en cours (DoNotInterrupt= non, il continue de jouer/boucler l'ancienne sĂ©lection MĂME SI elle n'appartient plus ĂDatabasesToSearch;InterruptOnDatabaseChange(AndInvalidateContinuingPose)= oui, force une recherche complĂšte). ChangerValidDatabasesne suffit donc JAMAIS Ă lui seul Ă faire rĂ©agir Motion Matching siGet_MMInterruptModene dĂ©tecte pas la transition responsable â vĂ©rifier scrupuleusement, pour TOUT nouveau contexte de sĂ©lection (nouvelle variable de state driving un chooser), qu'il existe bien une condition correspondante dans cette fonction (schĂ©ma dĂ©jĂ en place : une paireGetXxx/GetXxxLastFrame, mise Ă jour chaque frame dansUpdate_States, comparĂ©e avecUtilities|Enum|NotEqual(Enum)puis OR-Ă©e dans la condition racine). Diagnostic fiable :obj dumpsur l'instanceAnimInstancevivante en PIE (unreal.SystemLibrary.execute_console_command(actor, 'obj dump "<chemin_instance>"'), rĂ©sultat lu viaEditorToolset.LogsToolset.GetLogEntries) expose le struct COMPLETAnimGraphNode_MotionMatching=(...), notammentMotionMatchingState.SearchResult.(SelectedAnim|SelectedDatabase|bIsContinuingPoseSearch|SearchCost)etAnimPlayers[].InternalTimeAccumulator(qui doit AVANCER entre deux dumps espacĂ©s dans le temps â sinon la pose est rĂ©ellement figĂ©e, pas juste "en cours de transition"). -
PoseSearchDatabaseâ Ă©chec silencieux de build d'index et non-avancement figĂ© sur une frame (2026-09-06) : unPoseSearchDatabaseen modePCAKD_TREE(valeur par dĂ©faut) peut Ă©chouer Ă construire son index dĂšs le chargement du projet si son jeu d'animations sources est trop petit/peu variĂ© pour que le calcul PCA converge â logLogPoseSearch: Error: <hash> - <NomDatabase> BuildIndex Failed because of 'No Convergence' while calculating PCA data(visible uniquement viaGetLogEntriessurLogPoseSearch, jamais remontĂ© cĂŽtĂ© Blueprint/PIE). Tant que l'index reste dans cet Ă©tat, TOUTE recherche dessus Ă©choue en silence (SearchCost=FLT_MAX,SelectedAnim=None) et spamLogPoseSearch: Warning: UPoseSearchLibrary::MotionMatch - some searches have been skipped, since databases AsyncBuildIndex are in still in progress or failedĂ chaque tick. Fix testĂ© et qui fonctionne :db.set_editor_property("PoseSearchMode", unreal.PoseSearchMode.BRUTE_FORCE)(au lieu dePCAKD_TREE) + sauvegarde (EditorAssetLibrary.save_asset(path, only_if_is_dirty=False)â nĂ©cessite PIE ARRĂTĂ, sinon retourneFalsesans erreur) âBRUTE_FORCEn'a pas besoin de PCA et convient trĂšs bien Ă une petite database (coĂ»t de recherche linĂ©aire nĂ©gligeable Ă cette Ă©chelle). Second piĂšge indĂ©pendant, NON contournable trouvĂ© Ă ce jour : le tableauDatabaseAnimationAssets(alias historiqueAnimationAssets) d'unPoseSearchDatabaseest protĂ©gĂ© en lecture ET Ă©criture pour TOUTE mĂ©thode testĂ©e (get_editor_property/set_editor_propertyPython, ETObjectTools.get_properties/set_propertiesen C++ natif â qui pourtant contournent d'autres restrictions Python) ; seule la lecture BRUTE viaobj dump "<chemin>.<NomAsset>"(PAS juste<chemin>seul, qui ne dump que le Package) expose son contenu texte (DatabaseAnimationAssets(i)=(AnimAsset=...,SamplingRange=(Min=...,Max=...),...)), sans Ă©quivalent en Ă©criture connu. ATTENTION Ă la sĂ©mantique deSamplingRange(erreur de diagnostic commise puis corrigĂ©e le 2026-09-06) :(Min=0, Max=0)ne signifie PAS « plage vide » mais « ĂCHANTILLONNER TOUT LE CLIP » â c'est la valeur NORMALE, utilisĂ©e par toutes les databases saines du projet (vĂ©rifiĂ© surPSD_Dense_Stand_Walk_Loops,PSD_Dense_Stand_Idles). Le cas rĂ©ellement pathologique estMin == Max != 0, en particulier(longueur_du_clip, longueur_du_clip): fenĂȘtre de largeur nulle collĂ©e Ă la FIN du clip. Double consĂ©quence : (a) plus rien Ă lire, et (b)FPoseSearchDatabaseSequence::IsLooping()exigeSamplingRange == (0,0)EN PLUS deAnimSequence->bLoop, donc l'asset devient non-bouclable (bLoopAnimation=Falsedans le dump du nĆud) mĂȘme si l'AnimSequence source est bienLoop=Trueâ d'oĂč un gel sur une frame unique. SymptĂŽme observable :AnimPlayers[].InternalTimeAccumulatoridentique entre deuxobj dumpespacĂ©s de plusieurs secondes rĂ©elles en PIE. Correction = remettre la plage Ă0 / 0Ă la main dans l'Ă©diteur Pose Search Database. -
PIĂGE CRITIQUE â
EditorAssetLibrary.consolidate_assets()fait planter l'Ă©diteur sur certains types de classes (2026-09-08, dĂ©doublonnage de l'import Game Animation Sample) : cette fonction (fusionne toutes les rĂ©fĂ©rences d'un doublon vers l'asset gardĂ©, supprime le doublon, laisse unObjectRedirector) est fiable Ă 100% sur les assets de donnĂ©es pures (UserDefinedEnum, UserDefinedStruct, CurveFloat, ChooserTable, CameraRigAsset, CameraAsset, ControlRigBlueprint, ProxyAsset â testĂ© sur ~85 assets sans un seul Ă©chec) mais crashe le processus Ă©diteur de façon reproductible (Assertion failed: NewEditorElement.Private_GetInternalData()->GetRefCount() <= 1 ... The old and new element both have external references!,LogPython: Error: Python execution caused a crash (exception code: 0xC0000005)â l'Ă©diteur entier finit parEngine exit requested, pas juste l'interprĂ©teur Python) sur les ActorComponent Blueprints activement utilisĂ©s comme composant (constatĂ© surAC_PreCMCTick,AC_SmartObjectAnimation) et sur les Blueprint Interfaces largement implĂ©mentĂ©es (BPI_SandboxCharacter_Pawn). Les Blueprints "de classe" simples (GameMode, modes de mouvementMover, transitions) consolident sans problĂšme. Ne jamais retenterconsolidate_assetsune seconde fois sur le mĂȘme asset aprĂšs un premier crash â utiliser Ă la place, dans l'ordre de prĂ©fĂ©rence : (1)EditorAssetLibrary.delete_asset()en brut siAssetRegistry.get_referencers()confirme que plus rien ne rĂ©fĂ©rence le doublon (le plus sĂ»r, fonctionne mĂȘme sur les types Ă risque â mais peut prendre 1 Ă 4 minutes sur un projet avec des dizaines de milliers d'assets, l'appelexecute_python_codetimeout cĂŽtĂ© client mais l'opĂ©ration continue et rĂ©ussit cĂŽtĂ© serveur : revĂ©rifier viadoes_asset_existplutĂŽt que de conclure Ă un Ă©chec sur un timeout) ; (2) si des rĂ©fĂ©rences externes subsistent, les repointer manuellement d'abord âBlueprintTools.set_parent()pour un reparentage,BlueprintTools.retarget_node_class(node, old_class, new_class)pour un nĆud de cast/appel de fonction/Ă©vĂ©nement avec une classe figĂ©e Ă l'ancien doublon (fonctionne bien, contrairement Ăconsolidate_assets) â puisdelete_assetune fois les rĂ©fĂ©renceurs Ă zĂ©ro. Effet de bord du crash : le processus Ă©diteur entier redĂ©marre, ce qui remet l'interprĂ©teur Python Ă zĂ©ro mais PAS l'Ă©tat sauvegardĂ© sur disque â toute opĂ©ration dĂ©jĂ sauvegardĂ©e (compile+save) avant le crash est conservĂ©e ; seule la commande en cours au moment du crash est perdue. Toujours vĂ©rifieris_in_pie/unprint("ping")trivial aprĂšs CE type d'erreur avant de continuer : contrairement Ă une simple corruption d'interprĂ©teur (SystemError: unknown opcode, rĂ©cupĂ©rable seulement par redĂ©marrage Ă©diteur elle aussi), celle-ci relance le processus tout seul en quelques dizaines de secondes. -
Corollaire â reparenter un Blueprint dont les enfants rĂ©fĂ©rencent des COMPOSANTS PAR NOM (2026-09-08) : si un Blueprint enfant (ex.
SandboxCharacter_Mover_Ragdoll) a des nĆudsVariables|Default|GetXxx/SetXxxqui lisent des variables membres du PARENT (ex.SkeletalMesh,Capsule,CharacterMoverâ des variables de CACHE exposant les composants SCS rĂ©els, PAS les composants eux-mĂȘmes) et qu'on reparente vers un parent qui n'a pas ces variables sous ce nom exact, la compilation Ă©choue avecThe property associated with <Nom> could not be found. Fix simple et Ă fort effet de levier : ajouter au NOUVEAU parent des variables membres du mĂȘme nom/type exacts (BlueprintTools.add_object_variable/add_struct_variable/add_variable) â TOUS les nĆuds orphelins portant ce nom, dans TOUTES les fonctions de TOUS les enfants, se re-rĂ©solvent automatiquement Ă la compilation suivante, sans toucher un seul nĆud individuellement (testĂ© sur ~90 rĂ©fĂ©rences rĂ©parties dans 28 fonctions, rĂ©solu par l'ajout de 8 variables). Il n'est PAS nĂ©cessaire que ces variables soient effectivement peuplĂ©es/cĂąblĂ©es pour que la compilation rĂ©ussisse â seule leur EXISTENCE avec le bon nom/type compte pour le compilateur ; les peupler (ex. dansEventBeginPlay) reste nĂ©cessaire pour un comportement correct Ă l'exĂ©cution. -
connect_pins/write_graph_dslpeuvent devenir silencieusement des no-op aprĂšs une session trĂšs longue avec plusieurs crashs Ă©diteur (2026-09-08) : en fin de session, aprĂšs plusieurs cycles crash/redĂ©marrage,connect_pins(PinID_output, PinID_input)a cessĂ© de produire une erreur mais aussi de produire un effet (get_node_infosconfirme aprĂšs coup qu'aucune des deux pins n'est connectĂ©e) â reproduit mĂȘme sur une paire de nĆuds fraĂźchement créés dans le MĂME appel Python, et mĂȘme sur un Blueprint diffĂ©rent qui avait fonctionnĂ© plus tĂŽt dans la session. Aucune cause identifiĂ©e avec certitude (suspectĂ© : Ă©tat de l'Ă©diteur dĂ©gradĂ© par l'accumulation de crashs, pas un bug systĂ©matique de l'outil âconnect_pinsa fonctionnĂ© de façon fiable pendant le reste de la session). Siconnect_pinssemble rĂ©ussir sans erreur mais queget_node_infosne montre ensuite AUCUNE connexion sur les pins concernĂ©es, ne pas insister : passer Ă une mĂ©thode alternative (repenser le fix pour n'avoir besoin que d'ajouts de variables/fonctions, voir point ci-dessus) plutĂŽt que de perdre du temps Ă re-essayer la mĂȘme primitive. -
Ăcrire dans une
ChooserTable(colonnes) depuis un script (2026-09-06) :ColumnsStructsse LIT en Python (get_editor_property+.export_text()sur chaqueInstancedStruct) mais ne s'ĂCRIT PAS par cette voie âInstancedStruct.import_text(nouveau_texte)renvoieTrueen mentant (le contenu de l'Ă©lĂ©ment reste inchangĂ©), et leset_editor_property("ColumnsStructs", ...)qui suit ne remonte donc rien, sans lever d'exception. Voie qui fonctionne : le toolset Pythoneditor_toolset.toolsets.object.ObjectTools(importable directement :from editor_toolset.toolsets.object import ObjectTools), qui expose la table en JSON âjson.loads(ObjectTools.get_properties(chooser, ["ColumnsStructs"])), modification du dict (ex.col["rowValuesWithAny"][i] = "MatchAny"), puisObjectTools.set_properties(chooser, json.dumps(data))qui renvoieTrueet applique rĂ©ellement.ResultsStructs(rĂ©sultats des lignes) reste inaccessible par toutes les voies testĂ©es : on peut donc MODIFIER une ligne existante mais pas en AJOUTER une nouvelle par script. -
EditorAssetLibrary.save_asset/save_loaded_assetpeuvent renvoyerFalsealors que l'asset est parfaitement sauvegardable, PIE arrĂȘtĂ© et fichier non-verrouillĂ© (constatĂ© surCHT_PoseSearchDatabases_DenseaprĂšs une Ă©criture viaObjectTools.set_properties, probablement parce que le package n'est pas marquĂ© dirty par cette voie). Ne pas en conclure Ă un Ă©chec : passer parunreal.EditorLoadingAndSavingUtils.save_packages([obj.get_outermost()], False)qui renvoieTrueet met bien Ă jour lemtimedu.uasset(Ă vĂ©rifier viaos.path.getmtime, seule preuve fiable d'Ă©criture disque). -
Outillage découvert le 2026-09-13 (réparation post-migration) : (a)
BlueprintEditorLibrary.compile_blueprint/BlueprintTools.compile_blueprintne lĂšvent AUCUNE exception sur erreur de compilation â encadrer les compilations de marqueursunreal.log_warning("MARQUEUR")puis lireSaved/Logs/ProjectFv1.logentre les marqueurs (LogBlueprint: Error). (b)BlueprintTools.set_pin_value(et d'autres outils du toolset) peut SAUVEGARDER l'asset sur disque sans le dire â sauvegarder le fichier avant d'expĂ©rimenter. (c)retarget_node_class/change_member_variable_typene rafraĂźchissent pas les types de pins en cache (erreurs « X is not compatible with X ») : sauvegarder,EditorLoadingAndSavingUtils.reload_packages, recompiler â le rechargement reconstruit les nĆuds. (d) Le structPinIDn'est pas exposĂ© en Python : pourconnect_pins/break_pins, passer parProgrammaticToolset.execute_tool_script(appelget_execution_environmentrequis avant) avec des PinID JSON{direction, index_id, node:{refPath}}. (e) Les pins d'un nĆudEvaluate Chooserportent le NOM de l'asset struct de contexte : changer/renommer/fusionner la struct laisse des pins orphelines liĂ©es (« In use pin ... no longer exists ») Ă rebrancher. (f)EditorAssetLibrary.consolidate_assetssur desUserDefinedStructsauvegarde automatiquement les rĂ©fĂ©renceurs et crĂ©e les redirecteurs. (g)ChooserTable.ContextDatas'Ă©crit viaObjectTools.set_properties(JSON_structType/class/structârefPath) +EditorLoadingAndSavingUtils.save_packages. (h) Une rĂ©fĂ©rence passant par un.ini(ex.GameplayTagTableList) est invisible pour l'Asset Registry : vĂ©rifierConfig/avant de dĂ©clarer un asset « sans rĂ©fĂ©rence ». -
PIĂGE CRITIQUE â
consolidate_assetssur une UserDefinedEnum (probablement aussi une UserDefinedStruct) vide silencieusement les types de variables des rĂ©fĂ©renceurs (2026-09-14) : les rĂ©fĂ©rences dures sont réécrites, mais lePinSubCategoryObjectdes variables membres (et types de valeur de map) typĂ©es par l'enum fusionnĂ© tombe ĂNone: la variable devient un simplebyte. La classe compilĂ©e garde le bon type, donc tout compile. Au rechargement suivant du package (les rĂ©fĂ©renceurs sont auto-sauvegardĂ©s par la fusion), les liens devenus incompatibles sont supprimĂ©s, des nĆudsEqual/NotEqual (Enum)redeviennent Wildcard et l'Ă©diteur insĂšre desCastByteToEnum. Une entrĂ©e qui garde une valeur littĂ©rale compile toujours : la logique est fausse SANS erreur (ex.SandboxCharacter_Mover_ABP: 19 variables vidĂ©es â 2259 erreurs au rechargement ;BP_NotifyState_EarlyTransition: 5 liens perdus dont 1 sans erreur). LesK2Node_SwitchEnumne reconstruisent leurs sorties qu'au rechargement du package. ProcĂ©dure : sauvegarder tous les rĂ©fĂ©renceurs avant la fusion ; juste aprĂšs et AVANT tout rechargement, scannerBlueprintEditorLibrary.get_member_variable_type(bp, v).export_text()(PinSubCategoryObject=None) et retyper viachange_member_variable_type; si un rĂ©fĂ©renceur a dĂ©jĂ Ă©tĂ© rechargĂ© cassĂ©, le restaurer depuis la sauvegarde (Ă©diteur fermĂ©) ou comparer ses liens Ă un jumeau intact (BlueprintTools.get_node_infos), rebrancher et supprimer les casts (delete_node) ; valider parreload_packagesd'UN seul package Ă la fois (jamais un Blueprint en mĂȘme temps qu'un Blueprint dont il dĂ©pend). Pour des Blueprints entiers, prĂ©fĂ©rer un dĂ©placement Ă une fusion. -
CRASH ĂDITEUR â handles Python sur des nĆuds supprimĂ©s (2026-09-14) :
BlueprintTools.delete_nodepuiscompile_blueprintdans le MĂMEexec, alors que des variables Python gardent les handles de nĆuds / structs de pins (get_node_infos) des nĆuds supprimĂ©s âEXCEPTION_ACCESS_VIOLATIONdans python311.dll et fermeture de l'Ă©diteur. Fix qui a fonctionnĂ© : exĂ©cuter l'Ă©dition, la compilation/sauvegarde et tout ce qui dĂ©clenche un GC (suppression d'assets,reload_packages) dans des callbacksregister_slate_post_tick_callbackSĂPARĂS, chacun dans un dictionnaire de globals neuf, avecscope.clear()+gc.collect()entre les Ă©tapes etunreal.SystemLibrary.collect_garbage()au dĂ©but de l'Ă©tape suivante. Ne sauvegarder qu'aprĂšs une vĂ©rification : un crash ne laisse alors rien de corrompu sur disque. Relance :E:\UE_5.8\Engine\Binaries\Win64\UnrealEditor.exe "E:\projet\ProjectFv1\ProjectFv1.uproject"(MCP disponible ~20 s aprĂšs). -
Asset Registry périmé aprÚs sauvegarde + rechargement (2026-09-14) :
get_dependencies/get_referencerspeuvent encore lister une rĂ©fĂ©rence qu'un asset n'a plus (ex.PC_Sandboxâ widget de dĂ©mo retirĂ©, alors que le.uassetne contient plus ce nom). ForcerAssetRegistry.scan_paths_synchronous([dossier], True)avant de vĂ©rifier des rĂ©fĂ©renceurs. -
EditorAssetLibrary.delete_assetsur une map non chargée (/Game/dev_map) peut renvoyerTrueen laissant le.umapsur disque et une dépendance fantÎme dans l'Asset Registry (qui ferait recharger/réenregistrer la map lors d'un renommage de ses dépendances). Vérifier le fichier sur disque ; s'il reste, le supprimer puisscan_files_synchronous([fichier], True). -
Assigner un squelette Ă une animation qui n'en a pas (2026-09-14) :
AnimSequence.Skeletonest en lecture seule pourset_editor_propertyET refusé parObjectTools.set_properties; aucun service VibeUE (SkeletonService,AnimSequenceService,AnimMontageService) ne l'expose (lecture/compatibilité seulement). Seule voie : ouvrir l'asset dans l'éditeur, qui propose de choisir un squelette, puis sauvegarder. Avant, vérifier la compatibilité :AnimationLibrary.get_animation_track_names(anim)comparé aux os du mesh cible (SkinnedMeshComponent.get_num_bones/get_bone_namesur le composant mesh du CDO du personnage). -
Détecter des régressions d'assets binaires via git :
git show <commit>:<fichier> | git lfs smudgerestitue l'ancien.uasset; comparer l'ensemble des chaßnes/Game/...(table des noms) entre ancienne et nouvelle version révÚle les références perdues (lignes de chooser, bases d'un schéma, BPI d'un canal) sans ouvrir l'éditeur. -
Déplacer un dossier via
AssetTools.rename_assets(liste d'AssetRenameData, un seul appel pour tout le lot) réécrit et sauvegarde lui-mĂȘme les rĂ©fĂ©renceurs, sans laisser de redirecteur quand tous sont chargeables (112 assets en ~32 s le 2026-09-14). Le coĂ»t dĂ©pend du nombre de rĂ©fĂ©renceurs : un notify utilisĂ© par des milliers d'animations oblige Ă toutes les rĂ©enregistrer.
PiÚges PCG et éditeur rencontrés sur PCG/RoadNetwork (2026-10-28/29, détail dans Docs/PCG_RoutesPonts.md §5) :
EditorAssetLibrary.delete_assetsur un asset encore tenu par Python (ex. unPCGGraphjuste créé) Ă©choue avec un message « in use » et unensure, puis uncreate_assetdu 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_nodesur 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 pinIn, les binairesInA/InB(les deux doivent ĂȘtre branchĂ©s, mĂȘme sur la mĂȘme donnĂ©e).- OpĂ©ration unaire
SETd'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_selfvaut vrai par dĂ©faut (on ne voit que ce qui chevauche l'acteur) etbIgnoreSelfAndChildrenn'exclut pas la spline de l'acteur. Distance : utiliserSourceShape/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 = TrueviaObjectTools.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_screenshotattendent le premier plan (fenĂȘtre amenĂ©e devant par script). LandscapeService.get_height_at_location().heightne renvoie pas une hauteur monde en cm : prendre la hauteur parline_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_attributene filtre pas (chaque source copiĂ©e sur chaque cible) â filtrer puis copier par valeur. EnTARGET_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_FIRSTouseed_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: typeFSoftObjectPath(SoftObjectPathĂ©choue sans erreur). Un import CSV de DataTable avec des « problems » ouvre une boĂźte modale « Message » qui bloque le MCP.- DĂ©bogage : Export Selected Attributes (JSON) Ă©crit les points d'un nĆud dans un fichier ; reconstruire un graphe rĂ©gĂ©nĂšre tous les composants qui l'utilisent (le fichier est celui du dernier acteur).
10. Maintenir ce document Ă jour
Ce document doit toujours reflĂ©ter l'Ă©tat rĂ©el du projet. Un skill dĂ©diĂ© â maintain-architecture-doc (.claude/skills/maintain-architecture-doc/SKILL.md) â rappelle systĂ©matiquement aux modĂšles d'IA de :
- Consulter ce document avant de modifier la structure du projet.
- Le mettre à jour aprÚs toute création/suppression/déplacement/renommage de fichier ou dossier important.
- Ajouter une description pour tout nouveau fichier important.
- Retirer les entrées obsolÚtes (fichiers supprimés).
- Corriger les chemins aprÚs un déplacement.
- Mettre à jour les descriptions quand un systÚme évolue significativement.
- Vérifier périodiquement la cohérence entre ce document et l'arborescence réelle.
- Ne jamais laisser ce document dans un état sciemment obsolÚte aprÚs une modification de structure.
RĂšgle de detail : un fichier "important" Ă documenter est un Blueprint/Widget/Data Asset/Struct/Enum/Input Action qui porte de la logique ou des donnĂ©es de gameplay. Les assets purement artistiques individuels (textures, meshes, clips d'animation, miniatures) n'ont pas besoin d'entrĂ©e dĂ©diĂ©e â il suffit que leur dossier parent soit listĂ© et dĂ©crit (cf. §8).
Historique de nettoyage :
-
2026-09-04 :
Content/Systems/Blueprints/d/SandboxCharacter_CMC_ABPrenommé/déplacé versContent/Systems/Blueprints/SandboxCharacter_CMC_ABPvia l'outil de renommage Unreal (les 7 références ont été recùblées automatiquement, compilation vérifiée OK). -
2026-09-04 : suppression de 8 redirecteurs Unreal morts (résidus de renommages passés, 0 référence chacun, confirmés sans danger) :
Content/Systems/Stats/ACStats.uasset,Content/Systems/Movement/BPC_ClimbingComponent.uasset,Content/Systems/Movement/ClimbingMaterial.uasset,Content/Systems/Movement/CR_ClimbingGraphV2.uasset,Content/Systems/Movement/CR_Mannequin_BasicFootIK.uasset,Content/BP_TickManager.uasset,Content/dqs.uasset,Content/E_WeaponType.uasset. Les vraies versions de ces assets restent ĂContent/Systems/Movement/Climbing/,Content/Core/Tick/BP_TickManageretContent/Data/Enums/E_WeaponType. -
2026-09-13 : réparation aprÚs la migration
Project_FâProjectFv1(voir §8.2) â 782 fichiers UltraDynamicSky restaurĂ©s depuis git, contexte de 7 chooser tables remis surSystems/Blueprints, 3 structs identiques deContent/Blueprints/Data/fusionnĂ©es (redirecteurs), suppression deContent/Blueprints/SandboxCharacter_CMC+_ABP(doublon GASP), tagsFoley.Event.*/SmartObject.ObjectType.*ajoutĂ©s. Compilation complĂšte : 435 Blueprints, 0 erreur. -
2026-09-13 (nettoyage, étapes 1-2) : suppression des personnages de démo Echo/Paragon/UE4_Mannequin/UE5_Mannequins, de
MetaHumans/et des BPRetargetedCharacters/BP_*; rangement deSandboxCharacter_CMCâCore/Character/,BP_GameInstanceâCore/,DT_DemoTagsâData/(config mise Ă jour) ; suppression deDT_DemoTags.T3Det des dossiers vides (dontContent/Collections/,Content/Developers/). Compilation : 405 Blueprints, 0 erreur. -
2026-09-13/14 (nettoyage, étape 3) : suppression des redirecteurs morts aprÚs re-sauvegarde de leurs référenceurs (dont
Animations/anim_Swim*,Core/PlayerController/IA_InitiateClimb|IA_LeapFromClimb|IA_MovingClimb,PSD_Relaxed_Stand_Sprint_Pivots, les redirecteurs du 2026-09-04 encore suivis par git, et les redirecteurs de structs deContent/Blueprints/Data/). -
2026-09-14 : convergence des enums du framework dupliqué et réparation des Blueprints touchés (voir §8.2) ;
GM_DevâSandboxCharacter_CMC. Passe complĂšte : 405 Blueprints ; seule erreur restanteBP_Item_AdvancedRifle(Reload_Rifle_Hipsans squelette, antĂ©rieure) + avertissementUltra_Dynamic_Weather. Commit intermĂ©diaire (point de restauration) avant le dĂ©placement du reste deContent/Blueprints/versContent/Systems/Mover/. -
2026-09-14 (isolation du framework du sample) : démo GASP supprimée (
dev_map,Content/Levels/LevelPrototyping/,Content/Widgets/) aprĂšs avoir dĂ©tachĂ©AC_TraversalLogic(brancheLevelBlock_Traversable) etPC_Sandbox(widget de dĂ©mo) ; 17 redirecteurs d'enum supprimĂ©s ; 112 assets dĂ©placĂ©s sans fusion (Content/Blueprints/âSystems/Mover/saufAnimNotifies/,Aiming/âSystems/Aiming/,Content/Input/âSystems/Mover/Input/,E_WaponTypeâData/Enums/), rĂ©fĂ©rences réécrites, aucun redirecteur restant. ContrĂŽle aprĂšs redĂ©marrage complet de l'Ă©diteur : liens de graphe, valeurs de pins et types de variables des 66 Blueprints concernĂ©s encore existants identiques au relevĂ© pris avant le dĂ©placement (seuls Ă©carts : chemins réécrits et artefacts de l'outil de comparaison). Compilation complĂšte : 379 Blueprints, seule erreurBP_Item_AdvancedRifle(Reload_Rifle_Hipsans squelette, antĂ©rieure). -
2026-09-14 (reprise) : test PIE sur
MapDev1âGM_Devfait apparaĂźtreSandboxCharacter_CMC, aucune erreur de Blueprint Ă l'exĂ©cution. Seuls messages, antĂ©rieurs :Systems/Weather/UltraDynamicSky/Particles/SnowrĂ©fĂ©rence encore l'ancien chemin/Game/UltraDynamicSky/Particles/UDW_Niagara_Parameters, et 4 avertissements Pose Search d'entrĂ©es vides dansPSD_SwimmingIdle/PSD_SwimmingMovingSprint(contenu inchangĂ© depuisd29748b, de nouveau chargĂ© grĂące au chooser restaurĂ©). Restauration depuisd29748bdes 7 donnĂ©es Motion Matching dĂ©gradĂ©es par la migration (voir §8.2) avec fix MatchAny refait, et deNS_Tornado. Compilation complĂšte : 379 Blueprints, seule erreurBP_Item_AdvancedRifle(Reload_Rifle_Hipsans squelette, antĂ©rieure). -
2026-09-14 (météo) : corrections du systÚme météo projet (
WB_WeatherControl/WB_WeatherZone, voir §4 Weather). Bugs corrigĂ©s :setWeatherbetweenZonelisait deux fois Zone2 ;GetNearZonene trouvait jamais de zone (distances locales Ă 0, poids 0/0 et inversĂ©s) ;SetNuage/MakeTempretournaient 0 sans zone voisine (return dans la boucle) et clampaient la tempĂ©rature Ă 0â10 ;makestaterenvoyait un Ă©tat vide (branche froide nuages â„ 8) et ne calculait ni vent/brouillard/poussiĂšre ni humiditĂ© ;MakeForcastavait des pas de 0â1 s ;UpdateWeatherstaten'avançait jamais le temps (+0) ; rayon d'influence â 900 uu et triTrie zonepouvant boucler Ă l'infini ; overlaps dĂ©clenchĂ©s par n'importe quel acteur ; saison en secondes. Nouveaux : fonctionsStepForecast,ApplyToUDW,GetZoneState; variablesForecastStepMin/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 :WeatherDatades 2 zones de MapDev1 vide (0 °C / 0 %),BP_TickManagertransmet unDeltaTime~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_MoverreçoitAC_Cover+Arrow1, les variables et fonctions de cover/prone/nage, l'enregistrement du mode « Swimming » au BeginPlay, et ses fonctionsGet_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(contexteselfabsent desEvaluate Chooserâ branche Motion Matching inerte ; nouvelle basculeAnimBranchIndex). TestĂ© en PIE : prone (capsule 40 â 86 via leStanceModifier, basePSD_Dense_Prone_IdlessĂ©lectionnĂ©e), nage dansWaterBodyLake_0(entrĂ©e/flottaison Ă la profondeur cible/plongĂ©e/sortie,PSD_SwimmingIdlesĂ©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_ABPpasse entiĂšrement en Motion Matching âUpdate_Logicne calcule plus la bascule,AnimBranchIndexest fixĂ© Ă0(nĆudsSelect/Not Equal (Enum)/AND/Get StancesupprimĂ©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 = Noneet la tableSwimmingInDeepIdledu chooser est vide ; seulPSD_SwimmingMovingest rempli. Contournement dansCHT_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/Unequipreçoivent une brancheCast FailedâSandboxCharacter_Mover(leurCast To SandboxCharacter_CMCĂ©chouait en silence sur le Mover, d'oĂčWeapon/isArmedjamais renseignĂ©s). Nouvelle fonctionSandboxCharacter_Mover::SetEquippedWeapon+ variablesWeapon_Equip/WantToshotsur le pion,Weapon_Equip/Weapon_Equip Last Frame/Want ToshotsurSandboxCharacter_Mover_ABP(alimentĂ©es dansUpdate_PropertiesFromCharacter, thread principal).IA_AimrenseigneWantToshot.Update_MotionMatchingconsulte aussiCHT_PoseSearchDatabases_MoverquandIs Armed, etGet_MMInterruptModeforce l'interruption au changement d'arme. DansCHT_PoseSearchDatabases_Mover: colonnesIs ArmedetIS Moving ObjectrĂ©activĂ©es, ligne 1 (« Stand Idles Bow ») passĂ©e enGait = MatchAny. TestĂ© en PIE de bout en bout (ramassage â main â anims arc â visĂ©e â tir) avec non-rĂ©gression prone/nage.Inventory_Equipper.uassetapparaĂź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_GenericRetargetdepuis le commit initial (supprimé au nettoyage de la démo GASP), création deIK_MetaHuman_test,RTG_UEFN_to_MetaHuman_testetBP_VisualOverride_MetaHumandansSystems/Mover/VisualOverrides/,GM_Devreparenté surGM_Sandbox(il était vide) etVisualOverrides_Softrenseigné, défaut du CVarDDCvar.VisualOverridepassé 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]; nouveauSystems/Movement/ASTShared/(dĂ©pendances minimales des autres plugins AST) et map de testSystems/Movement/Test/L_ASTCoverTest;SandboxCharacter_MoverreçoitBPC_StateManager/BPC_CoverSystem/BPC_Interactionet les overrides de dĂ©placement ;SandboxCharacter_Mover_ABPlieOverlayGraphetInteractionIKGraph;IMC_Sandbox: A âIA_TakeCover; tables de tags AST ajoutĂ©es ĂDefaultGameplayTags.ini.AC_CoversupprimĂ© (par l'utilisateur). -
2026-10-28/29 : nouveau systĂšme
Content/PCG/RoadNetwork/(routes et ponts post-apo, voir §7 etDocs/PCG_RoutesPonts.md), dossier racineDocs/, ligneContent/Bridges/ajoutée en §8, piÚges PCG en §9. Le prototypeContent/PCG/Road/est conservé tel quel. Aucun asset existant modifié ni supprimé (seul le dossier d'essaiRoadNetwork/_Spike, créé et supprimé pendant le travail). -
2026-10-30 : nouveau systĂšme
Content/PCG/Haussmann/(immeubles haussmanniens, voir §7 etDocs/PCG_Haussmann.md+Docs/PCG_Haussmann_captures/), piÚges PCG ajoutés en §9 ; scripts hors projet dansE:/projet/PF_Haussmann_Work/scripts.