152 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/,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.
â **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_Cover, AC_TraversalLogic, AC_PreCMCTick, AC_VisualOverrideManagerâŠ
â
ââ 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)
â
âââ 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/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/
âââ SandboxCharacter_Mover.uasset â 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`
âââ SandboxCharacter_Mover_Ragdoll.uasset â Variante ragdoll du personnage Mover
âââ SandboxCharacter_Mover_ABP.uasset â Anim Blueprint du Mover (utilise `Systems/Aiming/ABP_AimingMaster`)
âââ 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/`)
âââ 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`
âââ 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.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/AC_Cover.uasset â ActorComponent : systĂšme de couverture (cover system)
â
âââ 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`). `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[]
â âââ 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 â ScrollBox_0 â InventoryPlayer` (WB_InventoryPlayer : Ă©quipements + poches + sac Ă dos dans le mĂȘme dĂ©filement) ; `InitializeWidgets` initialise `InventoryPlayer` et cĂąble `EquipSlotBACKPACK.OwnContainersHost = InventoryPlayer`. `Inventory_Player::GetQuickSlotItemInfo` lit les slots WEAPON/WEAPON2/Speed1/Speed2 via `InventoryScreen.InventoryPlayer`
â â âââ WB_InventoryPlayer.uasset â (2026-09-16) Fusion de WB_InventoryPart1 + WB_InventoryPart2 pour l'inventaire du joueur, en un seul bloc continu : `EquipsVertical` â `EquipSlotsBox` (SizeBox 740Ă860) â `SlotsCanvas` avec les 12 EquipSlots, puis `VerticalBox_0` (titre Pockets + `PocketContainer`, et les containers du sac Ă dos ajoutĂ©s dessous par `Add Container Below Pockets`). `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_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.
âââ 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/
â âââ _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)
âââ Road/
â âââ 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)
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/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 :
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.
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\.
Content/Data/DT_DemoTags.uasset (anciennement Ă la racine) : longtemps considĂ©rĂ© comme un reste de test sans rĂ©fĂ©rence â FAUX (vĂ©rifiĂ© le 2026-09-13) : c'est la table de tags AGIS dĂ©clarĂ©e dans Config/DefaultGameplayTags.ini, Ă conserver (voir §2.1).