Editor plugins¶
Engine plugins make a component run. Editor plugins make it editable: they tell the Inspector how to draw, add, and remove a component.
Without one, a registered component still shows up with a generic field editor. With one, you control labels, widgets, validation, and asset pickers.
The IPluginEditor interface¶
#include "PluginEditor.hpp"
namespace Editor {
class IPluginEditor {
public:
virtual ~IPluginEditor() = default;
virtual const char* GetName() const = 0;
virtual const char* GetIcon() const = 0;
virtual bool OnImGuiRender(Engine::Entity entity, Engine::Registry& registry) = 0;
virtual bool HasComponent(Engine::Entity entity, Engine::Registry& registry) = 0;
virtual void AddComponent(Engine::Entity entity, Engine::Registry& registry) = 0;
virtual void RemoveComponent(Engine::Entity entity, Engine::Registry& registry) = 0;
};
}
A minimal editor plugin¶
#include "Components/Health.hpp"
#include "PluginEditor.hpp"
#include <imgui.h>
namespace Editor {
class HealthPluginEditor : public IPluginEditor {
public:
const char* GetName() const override { return "Health"; }
const char* GetIcon() const override { return ICON_FA_HEART; }
bool HasComponent(Engine::Entity entity, Engine::Registry& registry) override {
return registry.HasComponent<Engine::Health>(entity);
}
bool OnImGuiRender(Engine::Entity entity, Engine::Registry& registry) override {
if (!HasComponent(entity, registry)) return false;
auto& health = registry.RequireComponent<Engine::Health>(entity);
ImGui::DragInt("Current", &health.current, 1.0f, 0, health.max);
ImGui::DragInt("Max", &health.max, 1.0f, 1, 9999);
ImGui::Checkbox("Invincible", &health.invincible);
return true;
}
void AddComponent(Engine::Entity entity, Engine::Registry& registry) override {
registry.AddComponent(entity, Engine::Health{});
}
void RemoveComponent(Engine::Entity entity, Engine::Registry& registry) override {
registry.RemoveComponent<Engine::Health>(entity);
}
};
}
Registering it¶
Add one line to InspectorPanel::InspectorPanel() in
Editor/src/Panels/InspectorPanel.cpp:
#include "Plugins/HealthPluginEditor.hpp"
m_PluginEditors.push_back(std::make_unique<HealthPluginEditor>());
Order in the vector is the order of sections in the Inspector.
Guidelines¶
- Do not duplicate engine defaults. If the generic editor already shows the fields correctly, skip the plugin.
- Use asset pickers for paths.
- Clamp early; drag widgets can emit out-of-range values.
- Keep serialization in sync: every field the inspector exposes must also be in
ComponentReflect.hpp. - No logic here. The editor only writes component data; systems do the work.