I was able to get this sort of working in UE 4.26.2.
In addition to the instructions in the video, I commented out the return false under if (Package->bIsCookedForEditor) in Engine\Source\Editor\UnrealEd\Private\Subsystems\AssetEditorSubsystem.cpp and compiled.
Since I don't really know C++, I didn't understand most of the code in the custom class- but I described the various errors I experienced to ChatGPT, and it produced the following modifications:
AssetDecooker.h:
// Youtube → Notorious R
#pragma once
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "UObject/NoExportTypes.h"
#include "Materials/Material.h"
#include "AssetDecooker.generated.h"
UCLASS()
class BLANKSANDBOX_API UAssetDecooker : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "Asset Tools", meta = (DisplayName = "Decook Assets"))
static void DecookAssets(TArray<UObject*> Objects);
};
AssetDecooker.cpp line 101:
if (lodData.SkinWeightVertexBuffer.GetNumVertices() > 0)
{
FSkinWeightInfo info = lodData.SkinWeightVertexBuffer.GetVertexSkinWeights(idx);
FMemory::Memcpy(vtx.InfluenceBones, info.InfluenceBones, sizeof(info.InfluenceBones));
FMemory::Memcpy(vtx.InfluenceWeights, info.InfluenceWeights, sizeof(info.InfluenceWeights));
}
AssetDecooker.cpp line 114:
if (range.Length > 0)
{
TArray<int32> indices2;
indices2.Reserve(range.Length);
for (uint32 l = 0; l < range.Length; ++l)
indices2.Add(renderSection.DuplicatedVerticesBuffer.DupVertData[range.Index + l]);
section.OverlappingVertices.Add(k, indices2);
}
AssetDecooker.cpp line 219:
if (UAnimSequence* typedAsset2 = Cast<UAnimSequence>(asset))
dstPackage = DecookAnimSequence(typedAsset2);
else if (USkeletalMesh* typedAsset3 = Cast<USkeletalMesh>(asset))
dstPackage = DecookSkeletalMesh(typedAsset3);
else if (UPhysicsAsset* typedAsset4 = Cast<UPhysicsAsset>(asset))
dstPackage = DecookPhysicsAsset(typedAsset4);
if (dstPackage != nullptr) {
FString packageName = dstPackage->GetName();
FString savePath = FPaths::ProjectContentDir() + packageName;
dstPackage->MarkPackageDirty();
UPackage::SavePackage(dstPackage, NULL, RF_Standalone, *savePath, GError, nullptr, false, true, SAVE_NoError);
savePackages.Add(dstPackage);
}
This code doesn't actually save the uncooked model in the correct directory, and you'll need to manually add the .uasset extension to the files it produces- probably easy fixes, but I'm dead tired of trying to get this to work, so I'll leave that for someone else to correct. Note also that you'll need to replace "BLANKSANDBOX" in AssetDecooker.h with the name of your project.
I was able to successfully uncook a skeletalmesh with this code and export a .fbx. This was a model with more than four skin weights per vertex, so neither umodel nor FModel were able to export it correctly (they discard the smallest weights when there are more than four, which led to serious clipping problems in this case). The model exported with this method, however, did have all of the correct skin weights. Thanks, Soulax!