L6e-CX-B09 : marges des UButton remises au defaut UE 4.27 (ERR-034, barre de temps decalee)
UE5 a change le style par defaut de UButton (FUMGCoreStyle, 12 px horizontaux au lieu de 2) ; les assets 4.27 ne stockent pas la marge par defaut. 430 boutons dans 46 Widget Blueprints, composante par composante, marges choisies par l'auteur conservees. Diff des 73 arbres UMG : seules les marges changent. CompileAllBlueprints inchange, build L6e 8561 paquets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
935d11f554
commit
7aaeb06816
51 changed files with 222 additions and 193 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -40,6 +40,7 @@ exporté dans `Docs/Migration/correctifs/` pour relecture.
|
|||
| CX-B05 | `LPFixDeprecatedNodes` (R-03) | 56 nœuds `SkeletalMesh`, 10 Blueprints | `GetSkeletalMeshAsset()` | **rejeté** : aggrave ERR-002 (16,6 → 35 `Accessed None`/perso) car les proxies sont des `USkinnedMeshComponent` | — | à refaire autrement (L7a) |
|
||||
| CX-B06 | `LPFixDeprecatedNodes` (R-04) | 6 nœuds, `AI`, `Person`, `Room` | `LPNavigationHelpers` | avertissements de dépréciation seulement | 5 | reporté (L7) |
|
||||
| CX-B08 | `LPFixParseIntoArray` (nouveau) | 114 nœuds `ParseIntoArray`, 17 Blueprints | rebranchés sur `LPStringCompat::ParseIntoArray` (algorithme UE 4.27) | UE5 renvoie `[""]` pour une chaîne vide : cause d'ERR-027 (personnages de quête invisibles/dévêtus) | 1 | **réimporté** (CHG-029), validé en jeu |
|
||||
| CX-B09 | `LPFixButtonPadding` (nouveau) | 430 `UButton`, 46 Widget Blueprints | marges des boutons remises au défaut UE 4.27 (Normal 2,2,2,2 ; Pressed 2,3,2,1), composante par composante | le style par défaut de `UButton` est passé à 12 px horizontaux en UE5 (`FUMGCoreStyle`) ; les assets 4.27 ne stockent pas la marge par défaut : cause d'ERR-034 (barre de temps décalée) | 1 | **réimporté** (CHG-033), validation en jeu en attente |
|
||||
| CX-B07 | `ResavePackages` | dossiers de gameplay (`BPs`, `UI`, `Structs`, `Scenes`, `Render`, `Characters`) | format UE5 | chargement plus rapide ; T-STAT-01 | 6 | après CX-B01 à B04 (L4) |
|
||||
|
||||
## 3. Protocole de réimport sous contrôle renforcé
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ règle §2 du document 03) : `Saved/Logs/portage/L3_game_20260929-012748.log` (n
|
|||
| T-STAT-02, 03, 04 | ✅ |
|
||||
|
||||
Découverte au passage : les erreurs `ParseIntoArray` (ERR-004) viennent de `GI.populateClothes4`,
|
||||
appelée par `Person.ReceiveBeginPlay`.
|
||||
appelée par `Person.ReceiveBeginPlay`.
|
||||
|
||||
|
||||
---
|
||||
|
|
@ -137,7 +137,7 @@ Tag d'entrée `L4-CX-B01-avant`. Sauvegarde : `D:\Game\LifePlay_Backup_5.5\L4-CX
|
|||
|
||||
| ID | Date | Lot | Fichiers | Raison | Avant → après | Retour arrière |
|
||||
|---|---|---|---|---|---|---|
|
||||
| CHG-018 | 2026-09-29 | L4-CX-B01 | `Content/BPs/GI.uasset` | réimport de CX-B01 (`LPFixAssetRegistryPins`) | MD5 `F4550DA5…` (UE4) → `0AA14EDB…` (UE5, réenregistré par la commandlet) | `Tools\Restore.ps1 -Lot L4-CX-B01` ou `git checkout L4-CX-B01-avant -- Content/BPs/GI.uasset` |
|
||||
| CHG-018 | 2026-09-29 | L4-CX-B01 | `Content/BPs/GI.uasset` | réimport de CX-B01 (`LPFixAssetRegistryPins`) | MD5 `F4550DA5…` (UE4) → `0AA14EDB…` (UE5, réenregistré par la commandlet) | `Tools\Restore.ps1 -Lot L4-CX-B01` ou `git checkout L4-CX-B01-avant -- Content/BPs/GI.uasset` |
|
||||
|
||||
### Sous-lot L4-CX-B02 — `EditableTextBoxStyle` (ERR-021) : essai 1 **rejeté**
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ campagne du 2026-09-07 avait utilisé cette commandlet : le défaut y était tr
|
|||
| CHG-021 | 2026-09-29 | L4 | `Tools/ReimportCorrectif.ps1` (nouveau) | automatisation des étapes 1 à 6 du protocole | `git rm` |
|
||||
|
||||
Enseignement pour le protocole : l'étape 5 (relecture du diff nœud par nœud) est indispensable ; ni la
|
||||
compilation ni le rapport de la commandlet n'ont détecté ce défaut.
|
||||
compilation ni le rapport de la commandlet n'ont détecté ce défaut.
|
||||
|
||||
### Sous-lot L4-CX-B02b — `EditableTextBoxStyle` (ERR-021) : essai 2 **validé**
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ Tag d'entrée `L4-CX-B02b-avant`. Sauvegarde : `D:\Game\LifePlay_Backup_5.5\L4-C
|
|||
| CHG-022 | 2026-09-29 | L4-CX-B02b | `Content/UI/StatMenu.uasset`, `Content/UI/CharGen.uasset` | réimport de CX-B02 | `34807BE0…` → `131E4B96…` ; `63CA2A78…` → `8D4E4200…` | `Tools\Restore.ps1 -Lot L4-CX-B02b` ou `git checkout L4-CX-B02b-avant -- Content/UI` |
|
||||
|
||||
**Effet sur les tests** : T-LOAD-01 (0 erreur de compilation) et T-LOAD-02 (0 broche orpheline) passent
|
||||
pour la première fois depuis le retour à la base saine.
|
||||
pour la première fois depuis le retour à la base saine.
|
||||
|
||||
### Sous-lot L4-CX-B03 — mur à échelle nulle dans `CentralLondon` (validé)
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ contrôle se fait par rapport de la commandlet avant/après (pas de graphe).
|
|||
|
||||
| ID | Date | Lot | Fichiers | Avant → après | Retour arrière |
|
||||
|---|---|---|---|---|---|
|
||||
| CHG-023 | 2026-09-29 | L4-CX-B03 | `Content/Scenes/CentralLondon.umap` | `C063EE72…` → `21912547…` | `Tools\Restore.ps1 -Lot L4-CX-B03` ou `git checkout L4-CX-B03-avant -- Content/Scenes` |
|
||||
| CHG-023 | 2026-09-29 | L4-CX-B03 | `Content/Scenes/CentralLondon.umap` | `C063EE72…` → `21912547…` | `Tools\Restore.ps1 -Lot L4-CX-B03` ou `git checkout L4-CX-B03-avant -- Content/Scenes` |
|
||||
|
||||
### Sous-lot L4-CX-B04 — événements `On Clicked` orphelins (validé)
|
||||
|
||||
|
|
@ -215,7 +215,7 @@ Tag d'entrée `L4-CX-B04-avant`. Sauvegarde : `D:\Game\LifePlay_Backup_5.5\L4-CX
|
|||
|
||||
| ID | Date | Lot | Fichiers | Avant → après | Retour arrière |
|
||||
|---|---|---|---|---|---|
|
||||
| CHG-024 | 2026-09-29 | L4-CX-B04 | `Content/UI/TopRight.uasset`, `Content/UI/CharGen.uasset` | `C34F7BB0…` → `B3B0ED10…` ; `8D4E4200…` → `A7C718C6…` | `Tools\Restore.ps1 -Lot L4-CX-B04` ou `git checkout L4-CX-B04-avant -- Content/UI` |
|
||||
| CHG-024 | 2026-09-29 | L4-CX-B04 | `Content/UI/TopRight.uasset`, `Content/UI/CharGen.uasset` | `C34F7BB0…` → `B3B0ED10…` ; `8D4E4200…` → `A7C718C6…` | `Tools\Restore.ps1 -Lot L4-CX-B04` ou `git checkout L4-CX-B04-avant -- Content/UI` |
|
||||
|
||||
### Build Development empaquetée `D:\Game\LifePlay_Build_5.5_L4` (2026-09-29)
|
||||
|
||||
|
|
@ -230,7 +230,7 @@ Tag d'entrée `L4-CX-B04-avant`. Sauvegarde : `D:\Game\LifePlay_Backup_5.5\L4-CX
|
|||
| T-RUN-02 à T-RUN-05 (génération de personnages, scène, sauvegarde, 30 min) | ⏳ **nécessite une partie jouée** : scénario `03_Plan_Migration_Tests.md` §4, sur cette build **et** sur la référence 4.27 |
|
||||
|
||||
Note : le `LifePlay.exe` à la racine de la build est un lanceur ; le processus du jeu est
|
||||
`Windows/LifePlay/Binaries/Win64/LifePlay.exe`.
|
||||
`Windows/LifePlay/Binaries/Win64/LifePlay.exe`.
|
||||
|
||||
### Correction de l'empaquetage — ERR-026 (2026-09-29)
|
||||
|
||||
|
|
@ -255,7 +255,7 @@ Build `D:\Game\LifePlay_Build_5.5_L4b` (`BuildCookRun` Development, journal `L4b
|
|||
| Test de fumée (150 s, sans intervention) | ✅ aucun plantage, fermeture propre ; une partie a démarré et 4 personnages ont été générés |
|
||||
| Premier A/B (`LogStats -Compare`, échantillon faible) | `Accessed None` maillage/perso **0,50** (4.27 : 0,27 ; 5.5 du 28/09 : 16,6) ; **4 acteurs distincts sur 4** (5.5 du 28/09 : tous `Person_C_0`) → CX-B01 corrige très probablement ERR-002 ; **à confirmer visuellement** (T-RUN-02 à 04) |
|
||||
|
||||
`LifePlay_Build_5.5_L4` (incomplète) est conservée comme preuve et peut être supprimée.
|
||||
`LifePlay_Build_5.5_L4` (incomplète) est conservée comme preuve et peut être supprimée.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -282,9 +282,9 @@ résolution chemin → asset (`GetAssetByObjectPath`, porté de `FName` vers `FS
|
|||
|
||||
| ID | Date | Lot | Fichiers | Raison | Retour arrière |
|
||||
|---|---|---|---|---|---|
|
||||
| CHG-027 | 2026-09-29 | L5 | `Source/LifePlay/LPAssetRegistryHelpers.cpp` | instrumentation permanente : tout chemin non résolu est signalé une fois (`LogLifePlay` Warning, chemin reçu et chemin interprété), réussites en `Verbose` | `Tools\Restore.ps1 -Lot L5-instr` |
|
||||
| CHG-027 | 2026-09-29 | L5 | `Source/LifePlay/LPAssetRegistryHelpers.cpp` | instrumentation permanente : tout chemin non résolu est signalé une fois (`LogLifePlay` Warning, chemin reçu et chemin interprété), réussites en `Verbose` | `Tools\Restore.ps1 -Lot L5-instr` |
|
||||
|
||||
Build `D:\Game\LifePlay_Build_5.5_L5a` (instrumentée) : éditeur et jeu compilés sans erreur ; cuisson `0 error(s), 0 warning(s)` ; T-PKG-01 : 8 561 packages ; test de fumée 180 s sans plantage (aucune partie démarrée : pas de sauvegarde dans cette build). En attente d'une scène de quête jouée.
|
||||
Build `D:\Game\LifePlay_Build_5.5_L5a` (instrumentée) : éditeur et jeu compilés sans erreur ; cuisson `0 error(s), 0 warning(s)` ; T-PKG-01 : 8 561 packages ; test de fumée 180 s sans plantage (aucune partie démarrée : pas de sauvegarde dans cette build). En attente d'une scène de quête jouée.
|
||||
|
||||
### Relevé `MeshSexRace` pendant une partie (build L5b, `-LPDumpVars`, 2026-09-29)
|
||||
|
||||
|
|
@ -298,9 +298,9 @@ Build `D:\Game\LifePlay_Build_5.5_L5a` (instrumentée) : éditeur et jeu compil
|
|||
|
||||
Suite : session 4.27 jouant les mêmes scènes de quête, puis comparaison normalisée.
|
||||
|
||||
Note de traçabilité : la sauvegarde `L5-instr` de `LPSessionLogSubsystem.*` a été prise après modification ; la version antérieure est dans git (`0baf4cf`).
|
||||
Note de traçabilité : la sauvegarde `L5-instr` de `LPSessionLogSubsystem.*` a été prise après modification ; la version antérieure est dans git (`0baf4cf`).
|
||||
|
||||
| CHG-028 | 2026-09-29 | L5 | `Source/LifePlay/LPSessionLogSubsystem.h/.cpp` | capteur d'exceptions de script (-LPTraceScriptEx, -LPTraceLocals, -LPTraceMax) : relève les variables locales du cadre Blueprint au moment de l'erreur ; actif seulement avec l'option (le moteur supprime sa pile d'appel quand un écouteur est branché : elle est réécrite). Validé en -game. | `Tools\Restore.ps1 -Lot L5-trace` |
|
||||
| CHG-028 | 2026-09-29 | L5 | `Source/LifePlay/LPSessionLogSubsystem.h/.cpp` | capteur d'exceptions de script (-LPTraceScriptEx, -LPTraceLocals, -LPTraceMax) : relève les variables locales du cadre Blueprint au moment de l'erreur ; actif seulement avec l'option (le moteur supprime sa pile d'appel quand un écouteur est branché : elle est réécrite). Validé en -game. | `Tools\Restore.ps1 -Lot L5-trace` |
|
||||
|
||||
### ERR-027 — cause racine identifiée (2026-09-29)
|
||||
|
||||
|
|
@ -376,3 +376,24 @@ Validation L6a (build `LifePlay_Build_5.5_L6a`, partie utilisateur 2026-09-30) :
|
|||
Capteur « read property Person » : relevé dans `GI::ReturnStatIfNeeded` (variable de scène `Player`, classe `Person`,
|
||||
tableau `Person` vide). Comparaison par personnage : `Dress` 0 sur cette partie (situationnel) ; variables `Person` vides
|
||||
3,3/perso en 4.27 contre 15 à 20 en 5.5 (ERR-003/ERR-030). Journal : `Saved/Logs/portage/L6a_LifePlay.log`.
|
||||
|
||||
### Lot L6e — ERR-034, marges des boutons (2026-09-30)
|
||||
|
||||
Captures utilisateur 4.27 / 5.5 : la rangée `<< < ❚❚ > >>` de `UI/TopRight` est plus espacée en 5.5 et déborde à droite.
|
||||
Photographie de l'arbre (`LPDumpWidgetTree`) : chaque bouton est un `UButton` (style transparent) autour d'un cercle de 30 px ;
|
||||
aucune marge n'est stockée dans l'asset. Source moteur : défaut 4.27 `FCoreStyle "Button"` NormalPadding (2,2,2,2),
|
||||
PressedPadding (2,3,2,1) ; défaut 5.5 `FUMGCoreStyle "Button"` (12,1.5,12,1.5) pour les deux. `FMargin` est sérialisé
|
||||
champ par champ par rapport au défaut : les assets 4.27 prennent donc la marge UE5 au chargement (+20 px par bouton).
|
||||
|
||||
| ID | Date | Lot | Fichiers | Raison | Retour arrière |
|
||||
|---|---|---|---|---|---|
|
||||
| CHG-032 | 2026-09-30 | L6e | `Source/LifePlayEditorTools/LPDumpWidgetTreeCommandlet.h/.cpp`, `LPFixButtonPaddingCommandlet.h/.cpp` (nouveaux) | outils : photographie des arbres UMG (`-BP=<nom>` ou `*`), correctif des marges | `git checkout L6e-avant -- Source` |
|
||||
| CHG-033 | 2026-09-30 | L6e-CX-B09 | 46 Widget Blueprints de `Content/UI` (liste : `etat/L6e-CX-B09_assets.txt`) | 429 boutons (passe 1, marges égales au défaut UE5) + 1 bouton (passe 2, `TopRight::Button_8` Pressed (12,2,12,2) : marge 4.27 partielle, Left/Right hérités d'UE5) remis au défaut UE4 ; 3 boutons à marge 0 choisie par l'auteur conservés | `Tools\Restore.ps1 -Lot L6e-CX-B09` |
|
||||
|
||||
| Contrôle | Résultat | Preuve |
|
||||
|---|---|---|
|
||||
| Simulation | 432 boutons vus, 429 à corriger, 46 paquets | `etat/L6e-CX-B09_dryrun.txt` |
|
||||
| Diff des 73 arbres UMG avant/après | hors lignes `WidgetStyle` : identiques ; dans `WidgetStyle`, seules `NormalPadding`/`PressedPadding` changent | `etat/L6e-CX-B09_widgets_{avant,apres,diff}.txt` |
|
||||
| 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` |
|
||||
|
|
|
|||
|
|
@ -38,4 +38,4 @@
|
|||
| 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-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 | ouvert — piste : mise en page UMG (métrique des polices / DPI) ; capture d'écran demandée |
|
||||
| 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) |
|
||||
|
|
|
|||
|
|
@ -1,177 +1,183 @@
|
|||
// Portage UE 5.5 - voir LPFixButtonPaddingCommandlet.h
|
||||
|
||||
#include "LPFixButtonPaddingCommandlet.h"
|
||||
|
||||
#include "AssetRegistry/AssetData.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "Blueprint/WidgetTree.h"
|
||||
#include "Components/Button.h"
|
||||
#include "Kismet2/BlueprintEditorUtils.h"
|
||||
#include "Kismet2/KismetEditorUtilities.h"
|
||||
#include "Misc/PackageName.h"
|
||||
#include "UObject/Package.h"
|
||||
#include "UObject/SavePackage.h"
|
||||
#include "WidgetBlueprint.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY_STATIC(LogLPFixButton, Log, All);
|
||||
|
||||
namespace
|
||||
{
|
||||
// Valeurs de UE 4.27 : Engine/Source/Runtime/SlateCore/Private/Styling/CoreStyle.cpp
|
||||
const FMargin UE4NormalPadding(2.f, 2.f, 2.f, 2.f);
|
||||
const FMargin UE4PressedPadding(2.f, 3.f, 2.f, 1.f);
|
||||
|
||||
FString Str(const FMargin& M)
|
||||
{
|
||||
return FString::Printf(TEXT("(%g,%g,%g,%g)"), M.Left, M.Top, M.Right, M.Bottom);
|
||||
}
|
||||
}
|
||||
|
||||
ULPFixButtonPaddingCommandlet::ULPFixButtonPaddingCommandlet()
|
||||
{
|
||||
IsClient = false;
|
||||
IsServer = false;
|
||||
IsEditor = true;
|
||||
LogToConsole = true;
|
||||
}
|
||||
|
||||
int32 ULPFixButtonPaddingCommandlet::Main(const FString& Params)
|
||||
{
|
||||
const bool bDryRun = Params.Contains(TEXT("DryRun"), ESearchCase::IgnoreCase);
|
||||
|
||||
// Defaut UE5 lu sur le CDO plutot que recopie : c'est lui que recoivent les boutons 4.27.
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
const FButtonStyle& UE5Style = GetDefault<UButton>()->WidgetStyle;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
const FMargin UE5Normal = UE5Style.NormalPadding;
|
||||
const FMargin UE5Pressed = UE5Style.PressedPadding;
|
||||
|
||||
UE_LOG(LogLPFixButton, Warning, TEXT("=== Marges de UButton : defaut UE5 Normal=%s Pressed=%s -> UE4 Normal=%s Pressed=%s%s ==="),
|
||||
*Str(UE5Normal), *Str(UE5Pressed), *Str(UE4NormalPadding), *Str(UE4PressedPadding),
|
||||
bDryRun ? TEXT(" [DRY RUN]") : TEXT(""));
|
||||
|
||||
FAssetRegistryModule& AssetRegistryModule =
|
||||
FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
|
||||
AssetRegistryModule.Get().SearchAllAssets(true);
|
||||
|
||||
TArray<FAssetData> Assets;
|
||||
AssetRegistryModule.Get().GetAssetsByClass(UWidgetBlueprint::StaticClass()->GetClassPathName(), Assets, true);
|
||||
|
||||
int32 ButtonsSeen = 0;
|
||||
int32 ButtonsFixed = 0;
|
||||
int32 ButtonsKept = 0;
|
||||
int32 BlueprintsModified = 0;
|
||||
int32 SaveFailures = 0;
|
||||
|
||||
for (const FAssetData& AssetData : Assets)
|
||||
{
|
||||
if (!AssetData.PackageName.ToString().StartsWith(TEXT("/Game/")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
UWidgetBlueprint* Blueprint = Cast<UWidgetBlueprint>(AssetData.GetAsset());
|
||||
if (!Blueprint || !Blueprint->WidgetTree)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TArray<UWidget*> Widgets;
|
||||
Blueprint->WidgetTree->GetAllWidgets(Widgets);
|
||||
|
||||
int32 FixedHere = 0;
|
||||
for (UWidget* Widget : Widgets)
|
||||
{
|
||||
UButton* Button = Cast<UButton>(Widget);
|
||||
if (!Button)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
++ButtonsSeen;
|
||||
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
FButtonStyle Style = Button->WidgetStyle;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
const bool bNormal = Style.NormalPadding == UE5Normal;
|
||||
const bool bPressed = Style.PressedPadding == UE5Pressed;
|
||||
if (!bNormal && !bPressed)
|
||||
{
|
||||
++ButtonsKept;
|
||||
UE_LOG(LogLPFixButton, Display, TEXT(" garde %s :: %s Normal=%s Pressed=%s"),
|
||||
*Blueprint->GetName(), *Button->GetName(), *Str(Style.NormalPadding), *Str(Style.PressedPadding));
|
||||
continue;
|
||||
}
|
||||
|
||||
UE_LOG(LogLPFixButton, Warning, TEXT(" %s :: %s Normal %s%s | Pressed %s%s"),
|
||||
*Blueprint->GetName(), *Button->GetName(),
|
||||
*Str(Style.NormalPadding), bNormal ? TEXT(" -> UE4") : TEXT(" (garde)"),
|
||||
*Str(Style.PressedPadding), bPressed ? TEXT(" -> UE4") : TEXT(" (garde)"));
|
||||
++ButtonsFixed;
|
||||
++FixedHere;
|
||||
|
||||
if (bDryRun)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (bNormal)
|
||||
{
|
||||
Style.NormalPadding = UE4NormalPadding;
|
||||
}
|
||||
if (bPressed)
|
||||
{
|
||||
Style.PressedPadding = UE4PressedPadding;
|
||||
}
|
||||
Button->Modify();
|
||||
Button->SetStyle(Style);
|
||||
}
|
||||
|
||||
if (FixedHere == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (bDryRun)
|
||||
{
|
||||
// Liste des paquets a sauvegarder (Snapshot) avant l'application reelle.
|
||||
UE_LOG(LogLPFixButton, Warning, TEXT(" paquet %s (%d bouton(s))"), *Blueprint->GetOutermost()->GetName(), FixedHere);
|
||||
continue;
|
||||
}
|
||||
|
||||
++BlueprintsModified;
|
||||
FBlueprintEditorUtils::MarkBlueprintAsModified(Blueprint);
|
||||
FKismetEditorUtilities::CompileBlueprint(Blueprint);
|
||||
|
||||
UPackage* Package = Blueprint->GetOutermost();
|
||||
FString Filename;
|
||||
if (!FPackageName::TryConvertLongPackageNameToFilename(
|
||||
Package->GetName(), Filename, FPackageName::GetAssetPackageExtension()))
|
||||
{
|
||||
++SaveFailures;
|
||||
UE_LOG(LogLPFixButton, Error, TEXT(" chemin introuvable pour %s"), *Package->GetName());
|
||||
continue;
|
||||
}
|
||||
|
||||
ResetLoaders(Package);
|
||||
|
||||
FSavePackageArgs SaveArgs;
|
||||
SaveArgs.TopLevelFlags = RF_Public | RF_Standalone;
|
||||
SaveArgs.SaveFlags = SAVE_None;
|
||||
SaveArgs.bWarnOfLongFilename = true;
|
||||
// GWarn et non GError : en commandlet, GError rend toute erreur de save fatale.
|
||||
SaveArgs.Error = GWarn;
|
||||
|
||||
if (UPackage::SavePackage(Package, nullptr, *Filename, SaveArgs))
|
||||
{
|
||||
UE_LOG(LogLPFixButton, Warning, TEXT(" -> %s sauvegarde (%d bouton(s))."), *Package->GetName(), FixedHere);
|
||||
}
|
||||
else
|
||||
{
|
||||
++SaveFailures;
|
||||
UE_LOG(LogLPFixButton, Error, TEXT(" -> ECHEC de sauvegarde de %s"), *Package->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
UE_LOG(LogLPFixButton, Warning,
|
||||
TEXT("=== Termine : %d bouton(s) vu(s), %d a la marge UE5 %s, %d garde(s), %d Widget Blueprint(s) modifie(s), %d echec(s) de sauvegarde. ==="),
|
||||
ButtonsSeen, ButtonsFixed, bDryRun ? TEXT("(a corriger)") : TEXT("corrige(s)"), ButtonsKept, BlueprintsModified, SaveFailures);
|
||||
|
||||
return SaveFailures > 0 ? 1 : 0;
|
||||
}
|
||||
// Portage UE 5.5 - voir LPFixButtonPaddingCommandlet.h
|
||||
|
||||
#include "LPFixButtonPaddingCommandlet.h"
|
||||
|
||||
#include "AssetRegistry/AssetData.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "Blueprint/WidgetTree.h"
|
||||
#include "Components/Button.h"
|
||||
#include "Kismet2/BlueprintEditorUtils.h"
|
||||
#include "Kismet2/KismetEditorUtilities.h"
|
||||
#include "Misc/PackageName.h"
|
||||
#include "UObject/Package.h"
|
||||
#include "UObject/SavePackage.h"
|
||||
#include "WidgetBlueprint.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY_STATIC(LogLPFixButton, Log, All);
|
||||
|
||||
namespace
|
||||
{
|
||||
// Valeurs de UE 4.27 : Engine/Source/Runtime/SlateCore/Private/Styling/CoreStyle.cpp
|
||||
const FMargin UE4NormalPadding(2.f, 2.f, 2.f, 2.f);
|
||||
const FMargin UE4PressedPadding(2.f, 3.f, 2.f, 1.f);
|
||||
|
||||
FString Str(const FMargin& M)
|
||||
{
|
||||
return FString::Printf(TEXT("(%g,%g,%g,%g)"), M.Left, M.Top, M.Right, M.Bottom);
|
||||
}
|
||||
/** Remplace par la valeur UE4 chaque composante egale au defaut UE5. Vrai si modifie. */
|
||||
bool FixMargin(FMargin& M, const FMargin& UE5, const FMargin& UE4)
|
||||
{
|
||||
const FMargin Before = M;
|
||||
if (M.Left == UE5.Left) { M.Left = UE4.Left; }
|
||||
if (M.Top == UE5.Top) { M.Top = UE4.Top; }
|
||||
if (M.Right == UE5.Right) { M.Right = UE4.Right; }
|
||||
if (M.Bottom == UE5.Bottom) { M.Bottom = UE4.Bottom; }
|
||||
return !(M == Before);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ULPFixButtonPaddingCommandlet::ULPFixButtonPaddingCommandlet()
|
||||
{
|
||||
IsClient = false;
|
||||
IsServer = false;
|
||||
IsEditor = true;
|
||||
LogToConsole = true;
|
||||
}
|
||||
|
||||
int32 ULPFixButtonPaddingCommandlet::Main(const FString& Params)
|
||||
{
|
||||
const bool bDryRun = Params.Contains(TEXT("DryRun"), ESearchCase::IgnoreCase);
|
||||
|
||||
// Defaut UE5 lu sur le CDO plutot que recopie : c'est lui que recoivent les boutons 4.27.
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
const FButtonStyle& UE5Style = GetDefault<UButton>()->WidgetStyle;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
const FMargin UE5Normal = UE5Style.NormalPadding;
|
||||
const FMargin UE5Pressed = UE5Style.PressedPadding;
|
||||
|
||||
UE_LOG(LogLPFixButton, Warning, TEXT("=== Marges de UButton : defaut UE5 Normal=%s Pressed=%s -> UE4 Normal=%s Pressed=%s%s ==="),
|
||||
*Str(UE5Normal), *Str(UE5Pressed), *Str(UE4NormalPadding), *Str(UE4PressedPadding),
|
||||
bDryRun ? TEXT(" [DRY RUN]") : TEXT(""));
|
||||
|
||||
FAssetRegistryModule& AssetRegistryModule =
|
||||
FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
|
||||
AssetRegistryModule.Get().SearchAllAssets(true);
|
||||
|
||||
TArray<FAssetData> Assets;
|
||||
AssetRegistryModule.Get().GetAssetsByClass(UWidgetBlueprint::StaticClass()->GetClassPathName(), Assets, true);
|
||||
|
||||
int32 ButtonsSeen = 0;
|
||||
int32 ButtonsFixed = 0;
|
||||
int32 ButtonsKept = 0;
|
||||
int32 BlueprintsModified = 0;
|
||||
int32 SaveFailures = 0;
|
||||
|
||||
for (const FAssetData& AssetData : Assets)
|
||||
{
|
||||
if (!AssetData.PackageName.ToString().StartsWith(TEXT("/Game/")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
UWidgetBlueprint* Blueprint = Cast<UWidgetBlueprint>(AssetData.GetAsset());
|
||||
if (!Blueprint || !Blueprint->WidgetTree)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TArray<UWidget*> Widgets;
|
||||
Blueprint->WidgetTree->GetAllWidgets(Widgets);
|
||||
|
||||
int32 FixedHere = 0;
|
||||
for (UWidget* Widget : Widgets)
|
||||
{
|
||||
UButton* Button = Cast<UButton>(Widget);
|
||||
if (!Button)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
++ButtonsSeen;
|
||||
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
FButtonStyle Style = Button->WidgetStyle;
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
// Composante par composante : FMargin est serialise champ par champ, une marge 4.27
|
||||
// partiellement modifiee (ex. Top/Bottom seuls) a recu les autres champs du defaut UE5.
|
||||
const FMargin OldNormal = Style.NormalPadding;
|
||||
const FMargin OldPressed = Style.PressedPadding;
|
||||
const bool bNormal = FixMargin(Style.NormalPadding, UE5Normal, UE4NormalPadding);
|
||||
const bool bPressed = FixMargin(Style.PressedPadding, UE5Pressed, UE4PressedPadding);
|
||||
if (!bNormal && !bPressed)
|
||||
{
|
||||
++ButtonsKept;
|
||||
UE_LOG(LogLPFixButton, Display, TEXT(" garde %s :: %s Normal=%s Pressed=%s"),
|
||||
*Blueprint->GetName(), *Button->GetName(), *Str(OldNormal), *Str(OldPressed));
|
||||
continue;
|
||||
}
|
||||
|
||||
UE_LOG(LogLPFixButton, Warning, TEXT(" %s :: %s Normal %s -> %s | Pressed %s -> %s"),
|
||||
*Blueprint->GetName(), *Button->GetName(),
|
||||
*Str(OldNormal), *Str(Style.NormalPadding), *Str(OldPressed), *Str(Style.PressedPadding));
|
||||
++ButtonsFixed;
|
||||
++FixedHere;
|
||||
|
||||
if (bDryRun)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Button->Modify();
|
||||
Button->SetStyle(Style);
|
||||
}
|
||||
|
||||
if (FixedHere == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (bDryRun)
|
||||
{
|
||||
// Liste des paquets a sauvegarder (Snapshot) avant l'application reelle.
|
||||
UE_LOG(LogLPFixButton, Warning, TEXT(" paquet %s (%d bouton(s))"), *Blueprint->GetOutermost()->GetName(), FixedHere);
|
||||
continue;
|
||||
}
|
||||
|
||||
++BlueprintsModified;
|
||||
FBlueprintEditorUtils::MarkBlueprintAsModified(Blueprint);
|
||||
FKismetEditorUtilities::CompileBlueprint(Blueprint);
|
||||
|
||||
UPackage* Package = Blueprint->GetOutermost();
|
||||
FString Filename;
|
||||
if (!FPackageName::TryConvertLongPackageNameToFilename(
|
||||
Package->GetName(), Filename, FPackageName::GetAssetPackageExtension()))
|
||||
{
|
||||
++SaveFailures;
|
||||
UE_LOG(LogLPFixButton, Error, TEXT(" chemin introuvable pour %s"), *Package->GetName());
|
||||
continue;
|
||||
}
|
||||
|
||||
ResetLoaders(Package);
|
||||
|
||||
FSavePackageArgs SaveArgs;
|
||||
SaveArgs.TopLevelFlags = RF_Public | RF_Standalone;
|
||||
SaveArgs.SaveFlags = SAVE_None;
|
||||
SaveArgs.bWarnOfLongFilename = true;
|
||||
// GWarn et non GError : en commandlet, GError rend toute erreur de save fatale.
|
||||
SaveArgs.Error = GWarn;
|
||||
|
||||
if (UPackage::SavePackage(Package, nullptr, *Filename, SaveArgs))
|
||||
{
|
||||
UE_LOG(LogLPFixButton, Warning, TEXT(" -> %s sauvegarde (%d bouton(s))."), *Package->GetName(), FixedHere);
|
||||
}
|
||||
else
|
||||
{
|
||||
++SaveFailures;
|
||||
UE_LOG(LogLPFixButton, Error, TEXT(" -> ECHEC de sauvegarde de %s"), *Package->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
UE_LOG(LogLPFixButton, Warning,
|
||||
TEXT("=== Termine : %d bouton(s) vu(s), %d a la marge UE5 %s, %d garde(s), %d Widget Blueprint(s) modifie(s), %d echec(s) de sauvegarde. ==="),
|
||||
ButtonsSeen, ButtonsFixed, bDryRun ? TEXT("(a corriger)") : TEXT("corrige(s)"), ButtonsKept, BlueprintsModified, SaveFailures);
|
||||
|
||||
return SaveFailures > 0 ? 1 : 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@
|
|||
// Les assets 4.27 n'enregistrent la marge que si elle differe du defaut UE4 : charges en 5.5,
|
||||
// leurs boutons prennent donc 20 px de large en plus (barre de temps de UI/TopRight decalee).
|
||||
//
|
||||
// La commandlet parcourt les Widget Blueprints de /Game et, pour chaque UButton dont une marge
|
||||
// vaut exactement le defaut UE5, remet le defaut UE4. Une marge differente (choisie par
|
||||
// l'auteur) n'est pas touchee.
|
||||
// La commandlet parcourt les Widget Blueprints de /Game et, pour chaque UButton, remplace par la
|
||||
// valeur UE4 chaque composante de marge egale au defaut UE5 (FMargin est serialise champ par
|
||||
// champ : une marge 4.27 partiellement modifiee a recu les autres champs du defaut UE5). Les
|
||||
// composantes choisies par l'auteur ne sont pas touchees. Idempotente.
|
||||
//
|
||||
// Usage :
|
||||
// UnrealEditor-Cmd.exe <projet> -run=LPFixButtonPadding [-DryRun]
|
||||
|
|
|
|||
Loading…
Reference in a new issue