Visualizer components are editor only components which helps us draw non-rendering debug information to the screen or HUD, this is more like a modular, lightweight, debug component that does not get shipped with packaged game.
Creating An Editor Module
To Create an editor module, you need to create a new folder with same name as your runtime module but postfix it by “Ed” or “Editor” for example:
Have the following files inside your module folder:
\Private\CustomModuleEd.cpp
\Public\CustomModuleEd.h
CustomModuleEd.Build.cs
In your build.cs file:
using UnrealBuildTool;
public class CustomModuleEd : ModuleRules
{
public CustomModuleEd(ReadOnlyTargetRules Target) : base(Target)
{
PrivateDependencyModuleNames.AddRange(new string[]
{
"Core",
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"UnrealEd",
"ComponentVisualizers"
});
}
}
And here is how your editor module class should look like:
#pragma once
#include "Modules/ModuleInterface.h"
#include "Modules/ModuleManager.h"
class FCustomModuleEd: public IModuleInterface
{
public:
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
#include "CustomModuleEd.h"
#include "UnrealEdGlobals.h"
#include "Editor/UnrealEdEngine.h"
IMPLEMENT_GAME_MODULE(FCustomModuleEd, CustomModuleEd);
void FCustomModuleEd::StartupModule() {}
void FCustomModuleEd::ShutdownModule() {}
Once everything is done you can now add your editor module into your plugin file:
{
"FileVersion": 3,
....
"Modules": [
{
"Name": "CustomPlugin",
"Type": "Runtime",
"LoadingPhase": "Default"
},
{
"Name": "CustomModuleEd",
"Type": "Editor",
"LoadingPhase": "PostEngineInit"
}
]
}
Make sure to set the loading phase to PostEngineInit, in case you want to check if your module is active in editor, you can go here Tools → Debug → Modules
Adding Component
The way visualization components works is by having a class type usually that is an actor component present outside the editor module that is attached to the actual Actor present inside your levels.
Hence, we need to create a dummy component inside our Runtime module, we are going to call it debugger component:
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class MYPROJECT_API UDebuggerComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UDebuggerComponent();
protected:
// Called when the game starts
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
public:
UPROPERTY(EditAnywhere, Category = "Debug")
float DrawDistance = 1000.0f;
UPROPERTY(EditAnywhere, Category = "Debug")
bool ShouldDrawDebugPoints = false;
};
Here we can also add properties, or we can simply read the properties from owning actor, but this component will act as an intermediary between our editor module visualizer and the data (Cover point locations) which exists inside our run-time module.
Add Visualizer Component in Editor Module
Create a new empty class inside the editor module and call it VisualizerComponent this will inherit from FComponentVisualizer.
/**
* Remove the API part of class definition because we don't want to expose this to other modules
*/
class TestVisualizer : public FComponentVisualizer
{
public:
virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI) override;
protected:
AActor* ActorRef; // Reference for actor which needs to show this debug
private:
FVector PerviousCameraLocation;
};
void TestVisualizer::DrawVisualization(const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI)
{
const UDebuggerComponent* debuggerComp = Cast<UDebuggerComponent>(Component);
if (!debuggerComp || !debuggerComp->ShouldDrawDebugPoints) { return; }
PDI->DrawPoint(ActorRef->GetActorLocation(), FLinearColor::Green, 25.0f, SDPG_Foreground);
}
To make this all work, you need to have your run-time debugger component added onto the actor you wish to have debug visualizers for, you can either do it manually in blueprints, instances or via C++ in constructor using default sub object.
Register your Visualizer in Editor Startup
The final step is to register your visualizer component and bind it with the debugger component during the startup function of your editor module.
Go back to the CustomModuleEd.cpp and implement the following:
void FCustomModuleEd::StartupModule()
{
if (GUnrealEd)
{
const TSharedPtr<TestVisualizer > TestViz = MakeShareable(new TestVisualizer ());
GUnrealEd->RegisterComponentVisualizer(UDebuggerComponent::StaticClass()->GetFName(), TestViz);
TestViz->OnRegister();
}
}
void FCustomModuleEd::ShutdownModule()
{
if (GUnrealEd)
{
GUnrealEd->UnregisterComponentVisualizer(UDebuggerComponent::StaticClass()->GetFName());
}
}
Now Compile and launch the editor, once you will select the actor which has the debugger component attached to it, the PDI will draw the debugs you mentioned in DrawVisualization function inside the class.
Top comments (0)