Copy morph targets from one SkeletalMesh to another

I would like to enable modders to copy morphs from one SkeletalMesh to another.

I wrote simple Python script to do that.


#Takes the last element of all selected stuff in the Content Browser
#Copies all morph targets from selection - excluding the last element - to the last element

#array =  from1,from2,from3, ... , lastElementThatTakesAll]


import unreal as ue
from unreal import SkeletalMesh, MorphTarget

# create unreal class instances
editor_util = ue.EditorUtilityLibrary()
#material_util=unreal.Material()

# get the selected assets
selected_assets = editor_util.get_selected_assets()

lastmesh=selected_assets[len(selected_assets)-1]

morphtargets=lastmesh.morph_targets
print("lastmesh morphs: ")
print(lastmesh.morph_targets)

for morphlist in selected_assets:
if(morphlist==lastmesh):break
print("List: ")
print( morphlist)
for morph in morphlist.morph_targets:
print("Morph: " )
print(morph)
morphtargets.append( morph)

lastmesh.morph_targets=morphtargets

It does work, I can see the sliders on the Receiver mesh in Persona…
The issue is it only works with identical meshes/duplicated ones… Not very useful.
If I import it with different settings the morph target sliders don’t do anything, even though the mesh is “nearly identical”.

I wrote BP node to do the same thing, but the results are the same… sliders are present, but aren’t doing anything.


bool UVictoryBPFunctionLibrary::AddMorphTargetToSkelMeshFromSkelMesh(USkeletalMesh* Receiver, USkeletalMesh* Sender) {
auto senderMorphs = Sender->MorphTargets;

for(auto morph : senderMorphs)
{
Receiver->MorphTargets.Add(morph);
}

return true;
}

I tried the RegisterMorphTarget function as well, but this one just crashed the editor.
Tried calling both in the construction script/beginplay as well.



bool UVictoryBPFunctionLibrary::AddMorphTargetToSkelMeshFromSkelMesh(USkeletalMesh* Receiver, USkeletalMesh* Sender) {
auto senderMorphs = Sender->MorphTargets;

for (auto morph : senderMorphs)
{
bool valid=Receiver->RegisterMorphTarget(morph,false);

//GEngine->AddOnScreenDebugMessage(-1,15.0f,FColor::Red,"morph name: "+morph->GetName());
}
return true;
}

EDIT:
This line causes the crash:


Receiver->InitMorphTargets();

Thats the nature of morph targets.
they work based on the DCC assigned vertex index/order

Since different meshes have different verticis it is not possible to just transfer the morph from A to B when A != B - at least in Index order.

]

Is there a way to reassign those id-s somehow inside UE or the DCC?

Nor really, in blender the fastest way is to delete all non morph faces and attach the morph to the new mesh.

That said, you may be able to brake down how they work and re-assign vertex index by looking at the source…

Did you ever get this sorted?

I used CopyMorphTools from the MarketPlace

Hello, A solution found? Other than the CopyMorphTools plugin?

Nope, but the plugin works quite well.

Could you please post the link here? I’m not finding that in the marketplace…did you mean this tool: Morph Tools Plugin in Code Plugins - UE Marketplace