Plugin not compiling. HComponentVisProxy unresolved external symbol

EDIT: Typically I figured this out right after posting.
I was missing 2 lines at the top of my cpp.

IMPLEMENT_HIT_PROXY(HControlPointVisProxy, HComponentVisProxy)
IMPLEMENT_HIT_PROXY(HControlPointProxy, HControlPointVisProxy)

This seems to get things compiling. I’ll check back in if the issue comes back.


Hi.
I’m making a Editor Mode plugin with a custom subclass of ComponentVisualizer.h. The plugin creates shapes in editor with handles to control them, similar to the Spline component.

I need to subclass ‘HComponentVisProxy’ to manage clicking on handles in the editor but as soon as I try access the sub-classed structs it fails to compile with the linker error below. If I pass it the base struct ‘HComponentVisProxy’ then everything compiles fine.

The compile fails on this line:

PDI->SetHitProxy(new HControlPointProxy(Component, i));

I’ve included “ComponentVisualizers” module in my Build.cs file so I should have access to the module.
I’m using this tutorial on the Wiki which suggests using a custom editor module,but I’d prefer to keep this in a plugin.

Any gems of wisdom would be very helpful. Am I hitting a limitation of plugins or am I just blind to something obvious?

Thanks in advance.

Error log:

1>GeometryControlComponentVisualizer.cpp.obj : error LNK2019: unresolved external symbol "public: static class HHitProxyType * __cdecl HControlPointVisProxy::StaticGetType(void)" (?StaticGetType@HControlPointVisProxy@@SAPEAVHHitProxyType@@XZ) referenced in function "public: virtual class HHitProxyType * __cdecl HControlPointVisProxy::GetType(void)const " (?GetType@HControlPointVisProxy@@UEBAPEAVHHitProxyType@@XZ)

1>GeometryControlComponentVisualizer.cpp.obj : error LNK2019: unresolved external symbol "public: static class HHitProxyType * __cdecl HControlPointProxy::StaticGetType(void)" (?StaticGetType@HControlPointProxy@@SAPEAVHHitProxyType@@XZ) referenced in function "public: virtual class HHitProxyType * __cdecl HControlPointProxy::GetType(void)const " (?GetType@HControlPointProxy@@UEBAPEAVHHitProxyType@@XZ)

1>C:\Projects\BuildingBuilder\Plugins\Builder\Binaries\Win64\UE4Editor-Builder-7084.dll : fatal error LNK1120: 2 unresolved externals

Declaring structs in FGeometryControlComponentVisualizer.h

#pragma once
#include "BuilderPrivatePCH.h"
#include "UnrealEd.h"
#include "ComponentVisualizer.h"
#include "Engine.h"

/** Base class for control point editing proxies */
struct HControlPointVisProxy : public HComponentVisProxy
{
	DECLARE_HIT_PROXY();

	HControlPointVisProxy(const UActorComponent* InComponent)
		: HComponentVisProxy(InComponent, HPP_Wireframe)
	{}
};

/** Proxy for a control point  */
struct HControlPointProxy : public HControlPointVisProxy
{
	DECLARE_HIT_PROXY();

	HControlPointProxy(const UActorComponent* InComponent, int32 InCPIndex)
		: HControlPointVisProxy(InComponent)
		, SelectedCPIndex(InCPIndex)
	{}

	int32 SelectedCPIndex;
};

class FGeometryControlComponentVisualizer : public FComponentVisualizer
{
public:
virtual void OnRegister() override;
	virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI) override;
}

Utilizing them in FGeometryControlComponentVisualizer.cpp

void FGeometryControlComponentVisualizer::DrawVisualization(const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI)
{
	if (const UGeometryControlComponent* ControlComp = Cast<const UGeometryControlComponent>(Component))
	{
		const FLinearColor SelectedColor = ControlComp->EditorSelectedColor;
		const FLinearColor UnselectedColor = ControlComp->EditorUnselectedColor;
		
		const TArray<FVector> ControlPoints = ControlComp->ControlPoints;

		for (int32 i = 0; i < ControlPoints.Num(); i++)
		{
			FLinearColor Color = (i == SelectedCPIndex) ? SelectedColor : UnselectedColor;

			int32 NextIdx = i + 1 > ControlPoints.Num() - 1 ? 0 : i + 1;	//Draw from last index back to first

			PDI->SetHitProxy(new HControlPointProxy(Component, i)); //Compile fails here
			PDI->DrawLine(ControlPoints[i], ControlPoints[NextIdx], Color, SDPG_Foreground);
			PDI->DrawPoint(ControlPoints[i], Color, 20.f, SDPG_Foreground);
			PDI->SetHitProxy(NULL);

		}
	}
}

Plugins Build.cs

PrivateDependencyModuleNames.AddRange(
			new string[]
			{
				"Core",
				"CoreUObject",
				"Engine",
				"Slate",
				"SlateCore",
				"InputCore",
				"UnrealEd",
				"LevelEditor",
				"ComponentVisualizers",
            }

Typically I figured this out right after posting. I was missing 2 lines at the top of my cpp.

IMPLEMENT_HIT_PROXY(HControlPointVisProxy, HComponentVisProxy) IMPLEMENT_HIT_PROXY(HControlPointProxy, HControlPointVisProxy)