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",
}