From cdce89a1118c8bf3d452a407aae4d27b96b04bba Mon Sep 17 00:00:00 2001 From: edujiro5972 <336072401+edujiro5972@users.noreply.github.com> Date: Wed, 30 Sep 2026 11:33:05 +0200 Subject: [PATCH] L6f : ERR-031 diagnostique - preexistant en 4.27 (camera SecondScreen sans racine), hors perimetre ; outil LPDumpComponents Co-Authored-By: Claude Opus 5.5 --- Docs/Migration/Journal_Modifications.md | 16 ++ Docs/Migration/Registre_Erreurs.md | 2 +- .../LPDumpComponentsCommandlet.cpp | 155 ++++++++++++++++++ .../LPDumpComponentsCommandlet.h | 27 +++ 4 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 Source/LifePlayEditorTools/LPDumpComponentsCommandlet.cpp create mode 100644 Source/LifePlayEditorTools/LPDumpComponentsCommandlet.h diff --git a/Docs/Migration/Journal_Modifications.md b/Docs/Migration/Journal_Modifications.md index 57fcf40..dbeb08c 100644 --- a/Docs/Migration/Journal_Modifications.md +++ b/Docs/Migration/Journal_Modifications.md @@ -397,3 +397,19 @@ champ par champ par rapport au défaut : les assets 4.27 prennent donc la marge | Idempotence | 3e simulation après passe 2 : 432 boutons vus, 0 à corriger | `etat/L6e-CX-B09c_LPFixButtonPadding_*.txt` | | `CompileAllBlueprints` | 0 erreur, 190 avertissements (identique à L4-CX-B08) | `etat/L6e-CX-B09_CompileAllBlueprints_*.txt` | | Build empaquetée `LifePlay_Build_5.5_L6e` | cuisson 0 erreur, 95 avertissements (inchangé) ; T-PKG-01 : 8561 `.uasset` | `Saved/Logs/portage/L6e_BuildCookRun.log` | + +### Lot L6f — ERR-031, portrait vide lors d'un appel (2026-09-30) : diagnostic, sans correctif + +Capture utilisateur 5.5 : l'encadré d'appel montre un dégradé de ciel. Chaîne établie : `GI::secondScreen` (contact lu dans +la variable DSL, `Person.secondScreen = true`, `Scene.FaceRender` visible) → `Render/SecondScreenMat` ← `SceneCapture2D` +`SecondScreen` de `CentralLondon` (rend seulement `Wall` et `PlayerCharacter`). La carte 4.27 d'origine (copie MD5 identique, +chargée temporairement sous `/Game/_Diag`, déplacée ensuite dans `D:\Game\LifePlay_Backup_5.5\L6f\_diag`) contient les +mêmes données : caméra sans racine, en position nulle. **L'utilisateur confirme le même défaut en 4.27** : ERR-031 est +préexistant, hors périmètre de la migration ; aucun asset modifié. + +| ID | Date | Lot | Fichiers | Raison | Retour arrière | +|---|---|---|---|---|---| +| CHG-034 | 2026-09-30 | L6f | `Source/LifePlayEditorTools/LPDumpComponentsCommandlet.h/.cpp` (nouveau) | outil de diagnostic : composants d'un Blueprint (`-BP=`) ou acteurs d'une carte (`-Map= -Filter=`), propriétés différentes du défaut | `git checkout L6f-avant -- Source` | + +Note d'outillage : `L6f_dump_GI.txt` a d'abord été écrasé par le vidage de `Person` (le script prenait le journal le plus +récent) ; il a été régénéré depuis `Saved/Logs/portage/L6f_LPDumpFunction_20260930-102202.log` (378 graphes). diff --git a/Docs/Migration/Registre_Erreurs.md b/Docs/Migration/Registre_Erreurs.md index 8704adb..c1bcfd2 100644 --- a/Docs/Migration/Registre_Erreurs.md +++ b/Docs/Migration/Registre_Erreurs.md @@ -35,7 +35,7 @@ | ERR-026 | Build Development incomplète : 3 257 packages cuits au lieu de 8 561 ; la plupart des maillages, vêtements, coiffures et textures manquent (chargés par chemin à l'exécution, invisibles pour le cuiseur) | retour utilisateur sur `LifePlay_Build_5.5_L4` | 5 304 packages | **bloquante** | L4 | corrigé (CHG-025) : `+DirectoriesToAlwaysCook=(Path="/Game")` ; test T-PKG-01 ajouté | | ERR-029 | Cuisson L5d : 95 avertissements (L5c : 0) | `L5d_BuildCookRun.log` | 95 | faible | L7a | **accepté** : ≈ 90 dépréciations `Get SkeletalMesh` (R-03) + 3 `GetRandomPointInNavigableRadius` (R-04) + 1 Unreal Trace Server ; visibles car la cuisson itérative a recompilé les 17 Blueprints modifiés par CX-B08 (L5c n'en recompilait aucun). Pas de régression | | ERR-030 | `Accessed None … Person` dans `GI::Dress` (appelée par `Room`) : habillage des PNJ de pièce | partie V1 du 2026-09-30 (42 min, 271 personnages) | 20 189 (74,5/perso ; 4.27 : 0) | faible (situationnel, pas d'effet visible) | L6b | ouvert — 0 occurrence sur la partie L6a (65 personnages) : dépend du lieu ou de la scène. Lié à ERR-003 : variables de scène `Person` vides 15 à 20/perso en 5.5 contre 3,3 en 4.27 ; `ReturnStatIfNeeded` lit la variable `Player` au tableau `Person` vide (capteur L6a). Le capteur doit pouvoir filtrer par fonction | -| ERR-031 | Le contact n'apparaît pas dans l'encadré lors d'un appel téléphonique | retour utilisateur 2026-09-30 | — | moyenne (visuel) | L6c | ouvert — piste : capture de visage (`SceneCapture`/`FaceTexture`) | +| ERR-031 | Le contact n'apparaît pas dans l'encadré lors d'un appel téléphonique | retour utilisateur 2026-09-30 | — | moyenne (visuel) | L6c | **préexistant en 4.27** (constaté par l'utilisateur le 2026-09-30, même encadré vide) : hors périmètre de la migration, non corrigé. Analyse : `UI/Scene::FaceRender` affiche `Render/SecondScreenMat` ← caméra `SecondScreen` de `CentralLondon` (liste « ShowOnly » : `Wall` + `PlayerCharacter`, scène à -3,1e6 / -1,5e7) ; dans la carte 4.27 d'origine, cette caméra a `RootComponent = None` et une position nulle, elle ne vise donc que le ciel | | ERR-032 | Scintillement à l'approche d'un personnage | retour utilisateur 2026-09-30 | — | moyenne (visuel) | L6a | **corrigé (CHG-031)**, validé en jeu le 2026-09-30 : on peut s'approcher des PNJ sans scintillement | | ERR-033 | Certaines actions demandent deux clics pour démarrer | retour utilisateur 2026-09-30 | — | moyenne (ergonomie) | L6d | ouvert — capture souris identique à 4.27 ; piste focus UMG (`InputMode:UIOnly … Non-Focusable widget`) | | ERR-034 | La barre de temps est décalée vers la droite | retour utilisateur 2026-09-30 | — | faible (visuel) | L6e | **corrigé (CHG-033, CX-B09)** — cause : marge par défaut des `UButton` passée de 2 px (UE4 `FCoreStyle`) à 12 px horizontaux (UE5 `FUMGCoreStyle`) ; 5 boutons × 20 px = 100 px de débordement ; validation en jeu en attente (build L6e) | diff --git a/Source/LifePlayEditorTools/LPDumpComponentsCommandlet.cpp b/Source/LifePlayEditorTools/LPDumpComponentsCommandlet.cpp new file mode 100644 index 0000000..089a777 --- /dev/null +++ b/Source/LifePlayEditorTools/LPDumpComponentsCommandlet.cpp @@ -0,0 +1,155 @@ +// Voir LPDumpComponentsCommandlet.h + +#include "LPDumpComponentsCommandlet.h" + +#include "AssetRegistry/AssetRegistryModule.h" +#include "Components/ActorComponent.h" +#include "Engine/Blueprint.h" +#include "Engine/SCS_Node.h" +#include "Engine/SimpleConstructionScript.h" +#include "Engine/Level.h" +#include "Engine/World.h" +#include "GameFramework/Actor.h" + +DEFINE_LOG_CATEGORY_STATIC(LogLPCompDump, Log, All); + +namespace +{ + void DumpObject(const UObject* Obj, bool bAll) + { + const UObject* Defaults = Obj->GetClass()->GetDefaultObject(); + for (TFieldIterator It(Obj->GetClass()); It; ++It) + { + const FProperty* Prop = *It; + if (Prop->IsA() || Prop->IsA()) + { + continue; + } + const bool bSame = Prop->Identical_InContainer(Obj, Defaults, 0, PPF_None); + if (bSame && !bAll) + { + continue; + } + FString Value; + Prop->ExportText_InContainer(0, Value, Obj, bSame ? nullptr : Defaults, const_cast(Obj), PPF_None); + if (Value.Len() > 4000) + { + Value = Value.Left(4000) + TEXT("..."); + } + UE_LOG(LogLPCompDump, Warning, TEXT(" %s%s = %s"), bSame ? TEXT("(defaut) ") : TEXT(""), *Prop->GetName(), *Value); + } + } +} + +ULPDumpComponentsCommandlet::ULPDumpComponentsCommandlet() +{ + IsClient = false; + IsServer = false; + IsEditor = true; + LogToConsole = true; +} + +int32 ULPDumpComponentsCommandlet::Main(const FString& Params) +{ + TArray Tokens, Switches; + TMap ParamsMap; + ParseCommandLine(*Params, Tokens, Switches, ParamsMap); + + const FString WantedBP = ParamsMap.FindRef(TEXT("BP")); + const FString WantedMap = ParamsMap.FindRef(TEXT("Map")); + const FString Filter = ParamsMap.FindRef(TEXT("Filter")); + const bool bAll = Switches.Contains(TEXT("All")); + if (WantedBP.IsEmpty() && WantedMap.IsEmpty()) + { + UE_LOG(LogLPCompDump, Error, TEXT("Usage : -BP= [-All] | -Map= -Filter= [-All]")); + return 1; + } + + // -Map : acteurs d'une carte dont la classe ou le nom contient le filtre. + if (!WantedMap.IsEmpty()) + { + UPackage* Package = LoadPackage(nullptr, *WantedMap, LOAD_None); + const UWorld* World = Package ? UWorld::FindWorldInPackage(Package) : nullptr; + if (!World || !World->PersistentLevel) + { + UE_LOG(LogLPCompDump, Error, TEXT("Carte '%s' introuvable."), *WantedMap); + return 1; + } + UE_LOG(LogLPCompDump, Warning, TEXT("=== %s : acteurs '%s' ==="), *WantedMap, *Filter); + for (const AActor* Actor : World->PersistentLevel->Actors) + { + if (!Actor || (!Filter.IsEmpty() && !Actor->GetClass()->GetName().Contains(Filter) && !Actor->GetName().Contains(Filter))) + { + continue; + } + UE_LOG(LogLPCompDump, Warning, TEXT(" [acteur] %s (%s) a %s"), *Actor->GetName(), *Actor->GetClass()->GetName(), + *Actor->GetActorLocation().ToString()); + DumpObject(Actor, bAll); + for (const UActorComponent* Comp : Actor->GetComponents()) + { + if (Comp) + { + UE_LOG(LogLPCompDump, Warning, TEXT(" [composant] %s (%s)"), *Comp->GetName(), *Comp->GetClass()->GetName()); + DumpObject(Comp, bAll); + } + } + } + return 0; + } + + FAssetRegistryModule& AssetRegistryModule = + FModuleManager::LoadModuleChecked(TEXT("AssetRegistry")); + AssetRegistryModule.Get().SearchAllAssets(true); + + TArray Assets; + AssetRegistryModule.Get().GetAssetsByClass(UBlueprint::StaticClass()->GetClassPathName(), Assets, true); + + const UBlueprint* Target = nullptr; + for (const FAssetData& AssetData : Assets) + { + if (AssetData.PackageName.ToString().StartsWith(TEXT("/Game/")) && AssetData.AssetName.ToString() == WantedBP) + { + Target = Cast(AssetData.GetAsset()); + break; + } + } + if (!Target || !Target->GeneratedClass) + { + UE_LOG(LogLPCompDump, Error, TEXT("Blueprint '%s' introuvable sous /Game."), *WantedBP); + return 1; + } + + UE_LOG(LogLPCompDump, Warning, TEXT("=== %s ==="), *Target->GetPathName()); + + const UObject* CDO = Target->GeneratedClass->GetDefaultObject(); + UE_LOG(LogLPCompDump, Warning, TEXT(" [CDO] %s"), *CDO->GetClass()->GetName()); + DumpObject(CDO, false); + + // Composants ajoutes dans l'editeur de Blueprint. + if (Target->SimpleConstructionScript) + { + for (const USCS_Node* Node : Target->SimpleConstructionScript->GetAllNodes()) + { + if (Node && Node->ComponentTemplate) + { + UE_LOG(LogLPCompDump, Warning, TEXT(" [SCS] %s (%s) parent=%s"), *Node->GetVariableName().ToString(), + *Node->ComponentTemplate->GetClass()->GetName(), *Node->ParentComponentOrVariableName.ToString()); + DumpObject(Node->ComponentTemplate, bAll); + } + } + } + + // Composants natifs (heritage C++) portes par le CDO. + if (const AActor* Actor = Cast(CDO)) + { + for (const UActorComponent* Comp : Actor->GetComponents()) + { + if (Comp) + { + UE_LOG(LogLPCompDump, Warning, TEXT(" [natif] %s (%s)"), *Comp->GetName(), *Comp->GetClass()->GetName()); + DumpObject(Comp, bAll); + } + } + } + return 0; +} diff --git a/Source/LifePlayEditorTools/LPDumpComponentsCommandlet.h b/Source/LifePlayEditorTools/LPDumpComponentsCommandlet.h new file mode 100644 index 0000000..601f4f3 --- /dev/null +++ b/Source/LifePlayEditorTools/LPDumpComponentsCommandlet.h @@ -0,0 +1,27 @@ +// Portage UE 5.5 - diagnostic (ERR-031). +// +// Liste les composants d'un Blueprint (modeles de la SimpleConstructionScript et composants +// herites du CDO) avec les proprietes qui different des valeurs par defaut de leur classe. +// Une propriete absente de la liste prend la valeur par defaut du moteur courant : c'est la +// qu'apparaissent les changements de defaut entre UE 4.27 et UE 5.5. Lecture seule. +// +// Usage : +// UnrealEditor-Cmd.exe -run=LPDumpComponents -BP= [-All] +// UnrealEditor-Cmd.exe -run=LPDumpComponents -Map=/Game/Scenes/X -Filter= [-All] +// -All : liste aussi les valeurs par defaut (toutes les proprietes) + +#pragma once + +#include "CoreMinimal.h" +#include "Commandlets/Commandlet.h" +#include "LPDumpComponentsCommandlet.generated.h" + +UCLASS() +class ULPDumpComponentsCommandlet : public UCommandlet +{ + GENERATED_BODY() + +public: + ULPDumpComponentsCommandlet(); + virtual int32 Main(const FString& Params) override; +};