Hi, I’m making a new class for my Unreal Engine project, and I’ve been wondering how I can draw different debug shape visualizations for my actor, but in the editor as well as in runtime. Something like Unreal’s collision components. When you add let’s say capsule component to your actor, you can see the capsule wireframe drawn in the editor.
So I started digging through Unreal’s source code and found that they use something called Scene Proxy. With a little bit of Googling, I found this blog post. And I though that was it. But, I can’t make it work. Here’s my code.
LesEditorVisComponent.h:
USTRUCT(BlueprintType)
struct LESDEBUG_API FLesEditorVisLine
{
GENERATED_BODY()
/// Start location relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector Start;
/// End location relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector End;
/// The colour of the line render
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FColor Colour;
/// The thickness of the line render
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Thickness;
FLesEditorVisLine(const FVector& InStart, const FVector& InEnd, const FColor& InColour, const float thickness):
Start(InStart),
End(InEnd),
Colour(InColour),
Thickness(thickness)
{
}
FLesEditorVisLine() :
Start(FVector::ZeroVector),
End(FVector(100, 0, 0)),
Colour(FColor::White),
Thickness(1.0f)
{
}
};
UCLASS(BlueprintType, Blueprintable,)
class LESDEBUG_API ULesEditorVisComponent : public UPrimitiveComponent
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<FLesEditorVisLine> Lines;
ULesEditorVisComponent(const FObjectInitializer& ObjectInitializer);
virtual FPrimitiveSceneProxy* CreateSceneProxy() override;
virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override;
};
LesEditorVisComponent.cpp:
ULesEditorVisComponent::ULesEditorVisComponent(const FObjectInitializer& ObjectInitializer) : UPrimitiveComponent(ObjectInitializer)
{
// set up some constants
PrimaryComponentTick.bCanEverTick = false;
SetCastShadow(false);
#if WITH_EDITORONLY_DATA
// Note: this makes this component invisible on level instances, not sure why
SetIsVisualizationComponent(true);
#endif
SetHiddenInGame(true);
bVisibleInReflectionCaptures = false;
bVisibleInRayTracing = false;
AlwaysLoadOnClient = false;
bIsEditorOnly = true;
}
FPrimitiveSceneProxy* ULesEditorVisComponent::CreateSceneProxy()
{
auto Ret = new FDebugRenderSceneProxy(this);
const FTransform& XForm = GetComponentTransform();
for (auto& L : Lines)
{
Ret->Lines.Add(FDebugRenderSceneProxy::FDebugLine(XForm.TransformPosition(L.Start),
XForm.TransformPosition(L.End), L.Colour, L.Thickness));
UE_LOG(LogTemp, Warning, TEXT("Draw Debug Line"));
}
return Ret;
}
FBoxSphereBounds ULesEditorVisComponent::CalcBounds(const FTransform& LocalToWorld) const
{
FBoxSphereBounds B = Super::CalcBounds(LocalToWorld);
for (auto& L : Lines)
{
// Re-centre the origin of the line to make box extents
FVector Extents = L.Start.GetAbs().ComponentMax(L.End.GetAbs());
B = B + FBoxSphereBounds(FVector::ZeroVector, Extents, Extents.GetMax());
}
return B.TransformBy(LocalToWorld);
}
The line UE_LOG(LogTemp, Warning, TEXT(“Draw Debug Line”)); does fire, and I can see the message in the log, but there’s no debug line drawn when I attach this component to an actor.
Does anyone have any idea why it’s not working?