Search code examples
c++unreal-engine4

Linking error in UE4 when GetAssetTools() is used in code


I created a C++ class derived from AssetActionUtility and wrote the following function in that class:

#include "ClipAnimUtility.h"

#include "EditorUtilityLibrary.h"
#include "IAssetTools.h"
#include "ClipAnimAsset.h"
#include "Kismet/KismetStringLibrary.h"

void UClipAnimUtility::ClipAnimCpp(FString path)
{
    AnimSource = UEditorUtilityLibrary::GetSelectedAssets()[0];
    PackagePath = UEditorUtilityLibrary::GetSelectedAssetData()[0].PackagePath.ToString();

    RowData = UClipAnimAsset::ReadFileArray(path);
    for (auto dataString : RowData)
    {
        FString startFrame{}, endFrame{}, clipName{}, subString{};

        dataString.Split("|", &startFrame, &subString);
        subString.Split("|", &endFrame, &clipName);

        SingleClip.StartFrame = UKismetStringLibrary::Conv_StringToInt(startFrame);
        SingleClip.EndFrame = UKismetStringLibrary::Conv_StringToInt(endFrame);
        SingleClip.ClipName = clipName;

        UAnimSequence* animSeq = Cast<UAnimSequence>(
            UAssetToolsHelpers::GetAssetTools()->DuplicateAsset(SingleClip.ClipName, PackagePath, AnimSource)
            );

        UClipAnimAsset::ClipAnimAsset(animSeq, SingleClip.StartFrame, SingleClip.EndFrame);
    }
}

And added the following modules into MyGame.Build.cs file:

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "AssetTools", "AssetRegistry" });

However, I was still getting link error LNK2019:

ClipAnimUtility.cpp.obj : error LNK2019: unresolved external symbol "public: static class TScriptInterface<class IAssetTools> __cdecl UAssetToolsHelpers::GetAssetTools(void)" (?GetAssetTools@UAssetToolsHelpers@@SA?AV?$TScriptInterface@VIAssetTools@@@@XZ) referenced in function "public: void __cdecl UClipAnimUtility::ClipAnimCpp(class FString)" (?ClipAnimCpp@UClipAnimUtility@@QEAAXVFString@@@Z)

It seems like it's complaining about not able to link the binaries associated with UAssetToolsHelpers, but according to the document this is included in the Module "AssetTools" which I've already included in the build.cs file, which is quite confusing. I am doing something wrong here?


Solution

  • Change the following code:

    UAnimSequence* animSeq = Cast<UAnimSequence>(
        UAssetToolsHelpers::GetAssetTools()->DuplicateAsset(SingleClip.ClipName, PackagePath, AnimSource)
        );
    

    into

    FAssetToolsModule& Module = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
    UAnimSequence* animSeq = Cast<UAnimSequence>(
        Module.Get().DuplicateAsset(SingleClip.ClipName, PackagePath, AnimSource)
        );