Code to make Blueprint_Reparent safer.
This commit is contained in:
BIN
Content/Testing/BP_Test.uasset
LFS
BIN
Content/Testing/BP_Test.uasset
LFS
Binary file not shown.
BIN
Content/Testing/WB_Test.uasset
LFS
Normal file
BIN
Content/Testing/WB_Test.uasset
LFS
Normal file
Binary file not shown.
@@ -44,6 +44,14 @@ public:
|
|||||||
UClass* NewParentClassObj = UWingTypes::TextToOneObjectType(Parent);
|
UClass* NewParentClassObj = UWingTypes::TextToOneObjectType(Parent);
|
||||||
if (!NewParentClassObj) return;
|
if (!NewParentClassObj) return;
|
||||||
|
|
||||||
|
// Validate reparent
|
||||||
|
if (!WingUtils::CanReparentBlueprint(BP->GeneratedClass, NewParentClassObj))
|
||||||
|
{
|
||||||
|
UWingServer::Printf(TEXT("Error: Cannot reparent %s to %s — incompatible class hierarchy.\n"),
|
||||||
|
*WingUtils::FormatName(BP), *WingUtils::FormatName(NewParentClassObj));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Perform reparent
|
// Perform reparent
|
||||||
BP->ParentClass = NewParentClassObj;
|
BP->ParentClass = NewParentClassObj;
|
||||||
FBlueprintEditorUtils::RefreshAllNodes(BP);
|
FBlueprintEditorUtils::RefreshAllNodes(BP);
|
||||||
|
|||||||
@@ -22,6 +22,11 @@
|
|||||||
#include "Misc/Paths.h"
|
#include "Misc/Paths.h"
|
||||||
#include "Misc/PackageName.h"
|
#include "Misc/PackageName.h"
|
||||||
|
|
||||||
|
// Reparent validation
|
||||||
|
#include "Engine/LevelScriptActor.h"
|
||||||
|
#include "Animation/AnimInstance.h"
|
||||||
|
#include "Blueprint/UserWidget.h"
|
||||||
|
|
||||||
// Animation Blueprint support
|
// Animation Blueprint support
|
||||||
#include "AnimStateNode.h"
|
#include "AnimStateNode.h"
|
||||||
#include "AnimStateTransitionNode.h"
|
#include "AnimStateTransitionNode.h"
|
||||||
@@ -397,6 +402,47 @@ bool WingUtils::CheckCanRename(UEdGraphNode* Node, const FString &Name)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// Reparent validation
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
|
bool WingUtils::CanReparentBlueprint(UClass* CurrentGenerated, UClass* Proposed)
|
||||||
|
{
|
||||||
|
if (!CurrentGenerated || !Proposed) return false;
|
||||||
|
|
||||||
|
UClass* CurrentParent = CurrentGenerated->GetSuperClass();
|
||||||
|
if (!CurrentParent) return false;
|
||||||
|
|
||||||
|
// Don't allow parenting to itself or one of its children
|
||||||
|
if (Proposed->IsChildOf(CurrentGenerated)) return false;
|
||||||
|
|
||||||
|
// Don't allow parenting to an interface
|
||||||
|
if (Proposed->IsChildOf(UInterface::StaticClass())) return false;
|
||||||
|
|
||||||
|
// LevelScriptActor blueprints stay in the LevelScriptActor hierarchy
|
||||||
|
if (CurrentParent->IsChildOf(ALevelScriptActor::StaticClass()))
|
||||||
|
return Proposed->IsChildOf(ALevelScriptActor::StaticClass());
|
||||||
|
|
||||||
|
// Actor blueprints stay in the Actor hierarchy, but not LevelScriptActor
|
||||||
|
if (CurrentParent->IsChildOf(AActor::StaticClass()))
|
||||||
|
return Proposed->IsChildOf(AActor::StaticClass()) &&
|
||||||
|
!Proposed->IsChildOf(ALevelScriptActor::StaticClass());
|
||||||
|
|
||||||
|
// Component blueprints stay in the ActorComponent hierarchy
|
||||||
|
if (CurrentParent->IsChildOf(UActorComponent::StaticClass()))
|
||||||
|
return Proposed->IsChildOf(UActorComponent::StaticClass());
|
||||||
|
|
||||||
|
// Anim blueprints stay in the AnimInstance hierarchy
|
||||||
|
if (CurrentParent->IsChildOf(UAnimInstance::StaticClass()))
|
||||||
|
return Proposed->IsChildOf(UAnimInstance::StaticClass());
|
||||||
|
|
||||||
|
// Widget blueprints stay in the UserWidget hierarchy
|
||||||
|
if (CurrentParent->IsChildOf(UUserWidget::StaticClass()))
|
||||||
|
return Proposed->IsChildOf(UUserWidget::StaticClass());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Blueprint helpers
|
// Blueprint helpers
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|||||||
@@ -255,6 +255,9 @@ public:
|
|||||||
static FString GetHandlerGroup(UClass* HandlerClass);
|
static FString GetHandlerGroup(UClass* HandlerClass);
|
||||||
static void PrintHandlerHelp(UClass* HandlerClass);
|
static void PrintHandlerHelp(UClass* HandlerClass);
|
||||||
|
|
||||||
|
// ----- Reparent validation -----
|
||||||
|
static bool CanReparentBlueprint(UClass* CurrentGenerated, UClass* Proposed);
|
||||||
|
|
||||||
// ----- Common Error Reporting -----
|
// ----- Common Error Reporting -----
|
||||||
static bool CheckExactlyOneNamed(int Count, const TCHAR *Kind, const FString &Name);
|
static bool CheckExactlyOneNamed(int Count, const TCHAR *Kind, const FString &Name);
|
||||||
static bool CheckExactlyNoneNamed(int Count, const TCHAR *Kind, const FString &Name);
|
static bool CheckExactlyNoneNamed(int Count, const TCHAR *Kind, const FString &Name);
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ public class UEWingman : ModuleRules
|
|||||||
"RHI",
|
"RHI",
|
||||||
"Slate",
|
"Slate",
|
||||||
"SlateCore",
|
"SlateCore",
|
||||||
"ToolMenus"
|
"ToolMenus",
|
||||||
|
"UMG"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user