NonStaticGH / CPathHostProject

This is a space where I develop Customizable Pathfinding plugin for UE5. Later on, I will also include my Engineering Thesis and documentation.
59 stars 14 forks source link

Cannot implement child of CPathVolume #6

Open Louspirit opened 1 year ago

Louspirit commented 1 year ago

Describe the bug

I tried to inherit from CPathVolume to add some custom methods. But whenever I call existing methods of the parent inside my new methods, it causes LNK2019 error when packaging.

Reproduction Steps

Declare CpathFinding module in my Game.Build.cs, in PublicDependencyModuleNames. Make a child class in the game module.

VerminExtermiantorCPathVolume.h

UCLASS()
class VERMINEXTERMINATOR_API AVerminExtermiantorCPathVolume : public ACPathVolume
{

Make some calls to parent methods:

VerminExtermiantorCPathVolume.cpp

FVector AVerminExtermiantorCPathVolume::FindNearestAvailableNodeLocationAroundLocation(FVector WorldLocation, TEnumAsByte<BlueprintUse::ESuccessBranches>& Branches)
{
    uint32 TempID;
    uint32 OriginTreeID = 0xFFFFFFFF;
    CPathOctree* OriginTree = FindLeafByWorldLocation(WorldLocation, OriginTreeID, false);

    if (!OriginTree) {
        Branches = BlueprintUse::ESuccessBranches::Failure;
        return FVector::Zero();
    }

    if (OriginTree && OriginTree->GetIsFree())
    {
        Branches = BlueprintUse::ESuccessBranches::Success;
        return WorldLocationFromTreeID(OriginTreeID);
    }

    uint32 Depth = FMath::Max((uint32)1, ExtractDepth(OriginTreeID) - 1);
    Depth = FMath::Min(Depth, (uint32)OctreeDepth);
    float SearchRange = GetVoxelSizeByDepth(Depth);

    // We double the search range
    FindClosestFreeLeaf(WorldLocation, TempID, SearchRange * 2);
    Branches = BlueprintUse::ESuccessBranches::Success;
    return WorldLocationFromTreeID(TempID);
}

Try to package the game and get the following error:

UATHelper: Packaging (Windows): VerminExtermiantorCPathVolume.cpp.obj : error LNK2019: symbole externe non r�solu "public: unsigned int __cdecl ACPathVolume::ExtractDepth(unsigned int)const " (?ExtractDepth@ACPathVolume@@QEBAII@Z) r�f�renc� dans la fonction "public: struct UE::Math::TVector<double> __cdecl AVerminExtermiantorCPathVolume::FindNearestAvailableNodeLocationAroundLocation(struct UE::Math::TVector<double>,class TEnumAsByte<enum BlueprintUse::ESuccessBranches> &)" (?FindNearestAvailableNodeLocationAroundLocation@AVerminExtermiantorCPathVolume@@QEAA?AU?$TVector@N@Math@UE@@U234@AEAV?$T
EnumAsByte@W4ESuccessBranches@BlueprintUse@@@@@Z)
UATHelper: Packaging (Windows): VerminExtermiantorCPathVolume.cpp.obj : error LNK2019: symbole externe non r�solu "public: float __cdecl ACPathVolume::GetVoxelSizeByDepth(int)const " (?GetVoxelSizeByDepth@ACPathVolume@@QEBAMH@Z) r�f�renc� dans la fonction "public: struct UE::Math::TVector<double> __cdecl AVerminExtermiantorCPathVolume::FindNearestAvailableNodeLocationAroundLocation(struct UE::Math::TVector<double>,class TEnumAsByte<enum BlueprintUse::ESuccessBranches> &)" (?FindNearestAvailableNodeLocationAroundLocation@AVerminExtermiantorCPathVolume@@QEAA?AU?$TVector@N@Math@UE@@U234@AEAV?$TEn
umAsByte@W4ESuccessBranches@BlueprintUse@@@@@Z)

Workaround

declare methods in child header file:

VerminExtermiantorCPathVolume.h

// Override inline parent methode because of link error.
    uint32 ExtractDepth(uint32 TreeID) const
    {
        return (TreeID & DEPTH_MASK) >> DEPTH_0_BITS;
    }

    // Override inline parent methode because of link error.
    float GetVoxelSizeByDepth(int Depth) const
    {
#if WITH_EDITOR
        checkf(Depth <= OctreeDepth, TEXT("CPATH - Graph Generation:::DEPTH was higher than OctreeDepth"));
#endif

        return LookupTable_VoxelSizeByDepth[Depth];
    }

Possible Solution

or

Targeted version

UE5.1

NonStaticGH commented 1 year ago

I didn't actually think someone would be using these methods. They need to be inline for performance reasons, but if declaring the body in .h file fixes the issue, I will look into it