Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix renaming issue with remove component #749

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 47 additions & 4 deletions Source/UnrealEnginePython/Private/UEPyEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1494,11 +1494,54 @@ PyObject *py_unreal_engine_remove_component_from_blueprint(PyObject *self, PyObj
return PyErr_Format(PyExc_Exception, "uobject is not a UBlueprint");
UBlueprint *bp = (UBlueprint *)py_obj->ue_object;

bp->Modify();
USCS_Node *ComponentNode = bp->SimpleConstructionScript->FindSCSNode(UTF8_TO_TCHAR(name));
if (ComponentNode)
// Copied From SSCSEditor::RemoveComponentNode(FSCSEditorTreeNodePtrType InNodePtr)
// Since simply removing the node causes rename issues if the component is re-created
// with the same name.
// Will probably cause issues if run on the root node of a blueprint
USCS_Node *SCS_Node = bp->SimpleConstructionScript->FindSCSNode(UTF8_TO_TCHAR(name));

if (SCS_Node != NULL)
{
bp->SimpleConstructionScript->RemoveNode(ComponentNode);
USimpleConstructionScript* SCS = SCS_Node->GetSCS();
check(SCS != nullptr);

// Remove node from SCS tree
SCS->RemoveNodeAndPromoteChildren(SCS_Node);

// Clear the delegate
SCS_Node->SetOnNameChanged(FSCSNodeNameChanged());

// on removal, since we don't move the template from the GeneratedClass (which we shouldn't, as it would create a
// discrepancy with existing instances), we rename it instead so that we can re-use the name without having to compile
// (we still have a problem if they attempt to name it to what ever we choose here, but that is unlikely)
// note: skip this for the default scene root; we don't actually destroy that node when it's removed, so we don't need the template to be renamed.
if (SCS_Node->ComponentTemplate != nullptr)
{
const FName TemplateName = SCS_Node->ComponentTemplate->GetFName();
const FString RemovedName = SCS_Node->GetVariableName().ToString() + TEXT("_REMOVED_") + FGuid::NewGuid().ToString();

SCS_Node->ComponentTemplate->Modify();
SCS_Node->ComponentTemplate->Rename(*RemovedName, /*NewOuter =*/nullptr, REN_DontCreateRedirectors);

UBlueprint* Blueprint = SCS->GetBlueprint();
if (Blueprint)
{
// Children need to have their inherited component template instance of the component renamed out of the way as well
TArray<UClass*> ChildrenOfClass;
GetDerivedClasses(Blueprint->GeneratedClass, ChildrenOfClass);

for (UClass* ChildClass : ChildrenOfClass)
{
UBlueprintGeneratedClass* BPChildClass = CastChecked<UBlueprintGeneratedClass>(ChildClass);

if (UActorComponent* Component = (UActorComponent*)FindObjectWithOuter(BPChildClass, UActorComponent::StaticClass(), TemplateName))
{
Component->Modify();
Component->Rename(*RemovedName, /*NewOuter =*/nullptr, REN_DontCreateRedirectors);
}
}
}
}
}

Py_RETURN_NONE;
Expand Down