O9 : collision retiree des arbres et voitures decoratifs de la carte (MapMarkers Tree/Car), commandlet LPSetComponentCollision
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
0ae5e29915
commit
8abf1d4ad8
4 changed files with 153 additions and 0 deletions
Binary file not shown.
|
|
@ -906,3 +906,4 @@ Validation L7c/L7d (2026-10-02, parc, même cadrage) : la nuit reste claire (sol
|
|||
| CHG-059 | 2026-10-02 | O0 | nouveaux `Tools/AuditAssets.py`, `Docs/Migration/11_Audit_Optimisation.md` ; lanceur `LifePlay_profil_O0.bat` (build L7cdj, hors dépôt) | audit d'optimisation en lecture seule : inventaire des assets, build livré, leviers et lots proposés ; aucune modification du projet | `git revert` du commit |
|
||||
| CHG-060 | 2026-10-02 | O0 | `Docs/Migration/11_Audit_Optimisation.md` §9-10 ; lanceur `LifePlay_profil_O0.bat` corrigé (capture par `-ExecCmds`) | résultats de la mesure en jeu (60 images/s tenues, à-coups du thread de jeu dus aux minuteries Blueprint, 463 Mo de physique) ; produits utiles de la bibliothèque Fab ; lots révisés | `git revert` du commit |
|
||||
| CHG-061 | 2026-10-02 | O1 | `LifePlay.uproject` (20 plugins limités à l'éditeur), `Config/DefaultGame.ini` (16 `DirectoriesToNeverCook`), nouveau `Tools/AuditScriptDeps.py` ; `README.md` : lien Mega de la V1.1 | build Shipping allégé de 387 Mo sans changement de contenu ; build `LifePlay_Build_5.5_O1` | `Tools\Restore.ps1 -Lot O1` ou `git checkout O1-avant -- LifePlay.uproject Config` |
|
||||
| CHG-062 | 2026-10-02 | O9 | nouvelle commandlet `LPSetComponentCollision` ; `Content/BPs/MapMarkers.uasset` : composants `Tree` et `Car` en `NoCollision` (diff avant/après : 2 lignes) | chargement de partie de 71 s (identique en 4.27) dû aux ≈ 160 000 corps physiques des arbres et voitures décoratifs de la carte (décision utilisateur : option 1) ; build `LifePlay_Build_5.5_O9` | `Tools\Restore.ps1 -Lot O9` |
|
||||
|
|
|
|||
121
Source/LifePlayEditorTools/LPSetComponentCollisionCommandlet.cpp
Normal file
121
Source/LifePlayEditorTools/LPSetComponentCollisionCommandlet.cpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
// Portage UE 5.5 - voir LPSetComponentCollisionCommandlet.h
|
||||
|
||||
#include "LPSetComponentCollisionCommandlet.h"
|
||||
|
||||
#include "Components/PrimitiveComponent.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
#include "Engine/SCS_Node.h"
|
||||
#include "Engine/SimpleConstructionScript.h"
|
||||
#include "Kismet2/KismetEditorUtilities.h"
|
||||
#include "Misc/PackageName.h"
|
||||
#include "UObject/Package.h"
|
||||
#include "UObject/SavePackage.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY_STATIC(LogLPSetCollision, Log, All);
|
||||
|
||||
ULPSetComponentCollisionCommandlet::ULPSetComponentCollisionCommandlet()
|
||||
{
|
||||
IsClient = false;
|
||||
IsServer = false;
|
||||
IsEditor = true;
|
||||
LogToConsole = true;
|
||||
}
|
||||
|
||||
int32 ULPSetComponentCollisionCommandlet::Main(const FString& Params)
|
||||
{
|
||||
TArray<FString> Tokens, Switches;
|
||||
TMap<FString, FString> ParamsMap;
|
||||
ParseCommandLine(*Params, Tokens, Switches, ParamsMap);
|
||||
const bool bDryRun = Switches.Contains(TEXT("DryRun"));
|
||||
const FString BPPath = ParamsMap.FindRef(TEXT("BP"));
|
||||
FString Profile = ParamsMap.FindRef(TEXT("Profile"));
|
||||
if (Profile.IsEmpty())
|
||||
{
|
||||
Profile = TEXT("NoCollision");
|
||||
}
|
||||
TArray<FString> Names;
|
||||
ParamsMap.FindRef(TEXT("Components")).ParseIntoArray(Names, TEXT(","), true);
|
||||
if (BPPath.IsEmpty() || Names.Num() == 0)
|
||||
{
|
||||
UE_LOG(LogLPSetCollision, Error, TEXT("Usage : -BP=/Game/BPs/X -Components=A,B [-Profile=NoCollision] [-DryRun]"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
const FString ObjectPath = BPPath + TEXT(".") + FPackageName::GetShortName(BPPath);
|
||||
UBlueprint* Blueprint = LoadObject<UBlueprint>(nullptr, *ObjectPath);
|
||||
if (!Blueprint || !Blueprint->SimpleConstructionScript)
|
||||
{
|
||||
UE_LOG(LogLPSetCollision, Error, TEXT("Blueprint introuvable ou sans SimpleConstructionScript : %s"), *ObjectPath);
|
||||
return 1;
|
||||
}
|
||||
|
||||
UE_LOG(LogLPSetCollision, Warning, TEXT("=== %s : composants [%s] -> profil %s%s ==="),
|
||||
*BPPath, *FString::Join(Names, TEXT(",")), *Profile, bDryRun ? TEXT(" [DRY RUN]") : TEXT(""));
|
||||
|
||||
TArray<UPrimitiveComponent*> Targets;
|
||||
int32 Errors = 0;
|
||||
for (const FString& Name : Names)
|
||||
{
|
||||
USCS_Node* Node = Blueprint->SimpleConstructionScript->FindSCSNode(FName(*Name));
|
||||
UPrimitiveComponent* Template = Node ? Cast<UPrimitiveComponent>(Node->ComponentTemplate) : nullptr;
|
||||
if (!Template)
|
||||
{
|
||||
++Errors;
|
||||
UE_LOG(LogLPSetCollision, Error, TEXT(" %s : composant primitif introuvable"), *Name);
|
||||
continue;
|
||||
}
|
||||
UE_LOG(LogLPSetCollision, Warning, TEXT(" %s [%s] : profil actuel %s, collision %d"),
|
||||
*Name, *Template->GetClass()->GetName(), *Template->GetCollisionProfileName().ToString(), (int32)Template->GetCollisionEnabled());
|
||||
Targets.Add(Template);
|
||||
}
|
||||
if (Errors > 0 || bDryRun)
|
||||
{
|
||||
return Errors > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
for (UPrimitiveComponent* Template : Targets)
|
||||
{
|
||||
Template->Modify();
|
||||
Template->SetCollisionProfileName(FName(*Profile));
|
||||
}
|
||||
FKismetEditorUtilities::CompileBlueprint(Blueprint);
|
||||
|
||||
// Verification apres compilation : relecture des modeles et des composants generes de la classe.
|
||||
for (const FString& Name : Names)
|
||||
{
|
||||
const USCS_Node* Node = Blueprint->SimpleConstructionScript->FindSCSNode(FName(*Name));
|
||||
const UPrimitiveComponent* Template = Node ? Cast<UPrimitiveComponent>(Node->ComponentTemplate) : nullptr;
|
||||
if (!Template || Template->GetCollisionProfileName() != FName(*Profile)
|
||||
|| (Profile == TEXT("NoCollision") && Template->GetCollisionEnabled() != ECollisionEnabled::NoCollision))
|
||||
{
|
||||
++Errors;
|
||||
UE_LOG(LogLPSetCollision, Error, TEXT(" %s : profil non applique"), *Name);
|
||||
continue;
|
||||
}
|
||||
UE_LOG(LogLPSetCollision, Warning, TEXT(" %s : profil %s, collision %d"), *Name,
|
||||
*Template->GetCollisionProfileName().ToString(), (int32)Template->GetCollisionEnabled());
|
||||
}
|
||||
if (Blueprint->Status == BS_Error)
|
||||
{
|
||||
++Errors;
|
||||
UE_LOG(LogLPSetCollision, Error, TEXT(" compilation en erreur"));
|
||||
}
|
||||
if (Errors > 0)
|
||||
{
|
||||
UE_LOG(LogLPSetCollision, Error, TEXT(" %d ecart(s) : Blueprint NON sauvegarde"), Errors);
|
||||
return 1;
|
||||
}
|
||||
|
||||
UPackage* Package = Blueprint->GetOutermost();
|
||||
const FString Filename = FPackageName::LongPackageNameToFilename(Package->GetName(), FPackageName::GetAssetPackageExtension());
|
||||
FSavePackageArgs SaveArgs;
|
||||
SaveArgs.TopLevelFlags = RF_Public | RF_Standalone;
|
||||
SaveArgs.Error = GWarn;
|
||||
if (!UPackage::SavePackage(Package, nullptr, *Filename, SaveArgs))
|
||||
{
|
||||
UE_LOG(LogLPSetCollision, Error, TEXT(" ECHEC de sauvegarde"));
|
||||
return 1;
|
||||
}
|
||||
UE_LOG(LogLPSetCollision, Warning, TEXT(" -> %s sauvegarde"), *Filename);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Portage UE 5.5 - lot O9 (optimisation ; defaut deja present en 4.27).
|
||||
//
|
||||
// Le chargement d'une partie prend ~70 s (4.27 comme 5.5). La trace Unreal Insights montre que 60 s
|
||||
// vont a la carte de la ville : MapMarkers.GenerateTrees ajoute ~160 000 instances aux composants
|
||||
// HierarchicalInstancedStaticMesh "Tree" et "Car", qui gardent la collision par defaut (BlockAll) :
|
||||
// chaque instance recoit un corps physique Chaos (HISMC_AddInstance 55 s, AddActorsToScene x161 000,
|
||||
// et ~460 Mo de physique en memoire). Ces arbres et voitures sont decoratifs (decision utilisateur).
|
||||
//
|
||||
// Cette commandlet change le profil de collision des composants nommes d'un Blueprint (noeuds de la
|
||||
// SimpleConstructionScript), recompile et sauvegarde. Controle : le profil et l'etat de collision
|
||||
// sont relus apres modification ; tout ecart, ou composant introuvable : rien n'est sauvegarde.
|
||||
//
|
||||
// Usage :
|
||||
// UnrealEditor-Cmd.exe <projet> -run=LPSetComponentCollision -BP=/Game/BPs/MapMarkers -Components=Tree,Car
|
||||
// [-Profile=NoCollision] [-DryRun]
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Commandlets/Commandlet.h"
|
||||
#include "LPSetComponentCollisionCommandlet.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class ULPSetComponentCollisionCommandlet : public UCommandlet
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
ULPSetComponentCollisionCommandlet();
|
||||
virtual int32 Main(const FString& Params) override;
|
||||
};
|
||||
Loading…
Reference in a new issue