PawnGlobal : Room::addObject bloque le canal Pawn, commandlet LPFixPawnResponse
Phase PawnGlobal (CHG-144). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
81f75d4e95
commit
3e773bf28b
3 changed files with 187 additions and 0 deletions
Binary file not shown.
165
Source/LifePlayEditorTools/LPFixPawnResponseCommandlet.cpp
Normal file
165
Source/LifePlayEditorTools/LPFixPawnResponseCommandlet.cpp
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
// Voir LPFixPawnResponseCommandlet.h
|
||||
|
||||
#include "LPFixPawnResponseCommandlet.h"
|
||||
|
||||
#include "EdGraph/EdGraph.h"
|
||||
#include "EdGraphSchema_K2.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
#include "Engine/SCS_Node.h"
|
||||
#include "Engine/SimpleConstructionScript.h"
|
||||
#include "K2Node_CallFunction.h"
|
||||
#include "Kismet2/BlueprintEditorUtils.h"
|
||||
#include "Kismet2/KismetEditorUtilities.h"
|
||||
#include "Misc/PackageName.h"
|
||||
#include "UObject/Package.h"
|
||||
#include "UObject/SavePackage.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY_STATIC(LogLPFixPawn, Log, All);
|
||||
|
||||
ULPFixPawnResponseCommandlet::ULPFixPawnResponseCommandlet()
|
||||
{
|
||||
IsClient = false;
|
||||
IsServer = false;
|
||||
IsEditor = true;
|
||||
LogToConsole = true;
|
||||
}
|
||||
|
||||
int32 ULPFixPawnResponseCommandlet::Main(const FString& Params)
|
||||
{
|
||||
const bool bDryRun = Params.Contains(TEXT("DryRun"), ESearchCase::IgnoreCase);
|
||||
UBlueprint* Room = LoadObject<UBlueprint>(nullptr, TEXT("/Game/BPs/Room.Room"));
|
||||
if (!Room)
|
||||
{
|
||||
UE_LOG(LogLPFixPawn, Error, TEXT("Blueprint Room introuvable"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
UK2Node_CallFunction* PawnNode = nullptr;
|
||||
UK2Node_CallFunction* TypeNode = nullptr;
|
||||
UK2Node_CallFunction* ScaleNode = nullptr;
|
||||
for (UEdGraph* Graph : Room->FunctionGraphs)
|
||||
{
|
||||
if (!Graph || Graph->GetName() != TEXT("addObject"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (UEdGraphNode* Node : Graph->Nodes)
|
||||
{
|
||||
UK2Node_CallFunction* Call = Cast<UK2Node_CallFunction>(Node);
|
||||
if (!Call)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const FName Function = Call->FunctionReference.GetMemberName();
|
||||
if (Function == TEXT("SetCollisionResponseToChannel"))
|
||||
{
|
||||
UEdGraphPin* Channel = Call->FindPin(TEXT("Channel"));
|
||||
if (Channel && Channel->DefaultValue == TEXT("ECC_Pawn"))
|
||||
{
|
||||
PawnNode = Call;
|
||||
}
|
||||
}
|
||||
else if (Function == TEXT("SetCollisionObjectType"))
|
||||
{
|
||||
TypeNode = Call;
|
||||
}
|
||||
else if (Function == TEXT("SetWorldScale3D"))
|
||||
{
|
||||
ScaleNode = Call;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!PawnNode || !TypeNode || !ScaleNode)
|
||||
{
|
||||
UE_LOG(LogLPFixPawn, Error, TEXT("noeuds addObject introuvables : Blueprint non sauvegarde"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
UEdGraphPin* Response = PawnNode->FindPin(TEXT("NewResponse"));
|
||||
UEdGraphPin* TypeChannel = TypeNode->FindPin(TEXT("Channel"));
|
||||
UEdGraphPin* PawnThen = PawnNode->FindPin(UEdGraphSchema_K2::PN_Then);
|
||||
UEdGraphPin* TypeExec = TypeNode->FindPin(UEdGraphSchema_K2::PN_Execute);
|
||||
UEdGraphPin* TypeThen = TypeNode->FindPin(UEdGraphSchema_K2::PN_Then);
|
||||
UEdGraphPin* ScaleExec = ScaleNode->FindPin(UEdGraphSchema_K2::PN_Execute);
|
||||
if (!Response || !TypeChannel || !PawnThen || !TypeExec || !TypeThen || !ScaleExec)
|
||||
{
|
||||
UE_LOG(LogLPFixPawn, Error, TEXT("broches introuvables : Blueprint non sauvegarde"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
UE_LOG(LogLPFixPawn, Warning, TEXT("Pawn %s, type %s"), *Response->DefaultValue, *TypeChannel->DefaultValue);
|
||||
const bool bPawnDone = Response->DefaultValue == TEXT("ECR_Block");
|
||||
const bool bTypeDone = TypeChannel->DefaultValue == TEXT("ECC_WorldDynamic") && TypeExec->LinkedTo.Contains(PawnThen);
|
||||
if (!bPawnDone && Response->DefaultValue != TEXT("ECR_Ignore"))
|
||||
{
|
||||
UE_LOG(LogLPFixPawn, Error, TEXT("reponse Pawn inattendue : Blueprint non sauvegarde"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32 Walls = 0;
|
||||
const TCHAR* WallNames[] = { TEXT("Wall1"), TEXT("Wall2"), TEXT("Wall3"), TEXT("Wall4") };
|
||||
if (!bDryRun)
|
||||
{
|
||||
if (!bPawnDone)
|
||||
{
|
||||
Response->DefaultValue = TEXT("ECR_Block");
|
||||
}
|
||||
if (!bTypeDone)
|
||||
{
|
||||
TypeChannel->DefaultValue = TEXT("ECC_WorldDynamic");
|
||||
PawnThen->BreakLinkTo(ScaleExec);
|
||||
TypeExec->BreakAllPinLinks();
|
||||
TypeThen->BreakAllPinLinks();
|
||||
PawnThen->MakeLinkTo(TypeExec);
|
||||
TypeThen->MakeLinkTo(ScaleExec);
|
||||
}
|
||||
if (Room->SimpleConstructionScript)
|
||||
{
|
||||
for (const TCHAR* Name : WallNames)
|
||||
{
|
||||
USCS_Node* Node = Room->SimpleConstructionScript->FindSCSNode(FName(Name));
|
||||
UPrimitiveComponent* Wall = Node ? Cast<UPrimitiveComponent>(Node->ComponentTemplate) : nullptr;
|
||||
if (!Wall)
|
||||
{
|
||||
UE_LOG(LogLPFixPawn, Error, TEXT("mur %s introuvable"), Name);
|
||||
return 1;
|
||||
}
|
||||
Wall->Modify();
|
||||
Wall->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
|
||||
Wall->SetCollisionObjectType(ECC_WorldDynamic);
|
||||
Wall->SetCollisionResponseToChannel(ECC_Pawn, ECR_Block);
|
||||
++Walls;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UE_LOG(LogLPFixPawn, Warning, TEXT("=== addObject Pawn Block, type WorldDynamic, %d murs%s ==="),
|
||||
bDryRun ? 4 : Walls, bDryRun ? TEXT(" [DRY RUN]") : TEXT(""));
|
||||
if (bDryRun)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
FBlueprintEditorUtils::MarkBlueprintAsStructurallyModified(Room);
|
||||
FKismetEditorUtilities::CompileBlueprint(Room);
|
||||
UPackage* Package = Room->GetOutermost();
|
||||
FString Filename;
|
||||
if (!FPackageName::TryConvertLongPackageNameToFilename(Package->GetName(), Filename, FPackageName::GetAssetPackageExtension()))
|
||||
{
|
||||
UE_LOG(LogLPFixPawn, Error, TEXT("chemin introuvable"));
|
||||
return 1;
|
||||
}
|
||||
ResetLoaders(Package);
|
||||
FSavePackageArgs SaveArgs;
|
||||
SaveArgs.TopLevelFlags = RF_Public | RF_Standalone;
|
||||
SaveArgs.SaveFlags = SAVE_None;
|
||||
SaveArgs.bWarnOfLongFilename = true;
|
||||
SaveArgs.Error = GWarn;
|
||||
if (!UPackage::SavePackage(Package, nullptr, *Filename, SaveArgs))
|
||||
{
|
||||
UE_LOG(LogLPFixPawn, Error, TEXT("sauvegarde echouee"));
|
||||
return 1;
|
||||
}
|
||||
UE_LOG(LogLPFixPawn, Warning, TEXT("Room sauvegarde : meubles et murs en WorldDynamic, Pawn Block"));
|
||||
return 0;
|
||||
}
|
||||
22
Source/LifePlayEditorTools/LPFixPawnResponseCommandlet.h
Normal file
22
Source/LifePlayEditorTools/LPFixPawnResponseCommandlet.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Room::addObject : Pawn Block, et le type d'objet du meuble devient WorldDynamic
|
||||
// (la capsule Person ignore WorldStatic, donc Pawn Block seul ne l'arrete pas).
|
||||
// Les quatre murs du Blueprint passent aussi en WorldDynamic et bloquent Pawn.
|
||||
// Tout ecart : Blueprint non sauvegarde.
|
||||
//
|
||||
// Usage :
|
||||
// UnrealEditor-Cmd.exe <projet> -run=LPFixPawnResponse [-DryRun]
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Commandlets/Commandlet.h"
|
||||
#include "LPFixPawnResponseCommandlet.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class ULPFixPawnResponseCommandlet : public UCommandlet
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
ULPFixPawnResponseCommandlet();
|
||||
virtual int32 Main(const FString& Params) override;
|
||||
};
|
||||
Loading…
Reference in a new issue