122 lines
4.3 KiB
C++
122 lines
4.3 KiB
C++
|
|
// 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;
|
||
|
|
}
|