// 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 Tokens, Switches; TMap 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 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(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 Targets; int32 Errors = 0; for (const FString& Name : Names) { USCS_Node* Node = Blueprint->SimpleConstructionScript->FindSCSNode(FName(*Name)); UPrimitiveComponent* Template = Node ? Cast(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(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; }