Your first C# plugin
Build a small panel for the editor in C#, change it while the editor runs, and give it a command you can undo. About ten minutes.
Editor plugins add panels, commands, settings pages, importers, asset types and viewport tools. You write them in C#, save, and the running editor rebuilds and reloads them. You do not install .NET: the editor builds plugins with the engine's own pinned SDK.
Create the plugin
- Tools › Plugins › New Editor Plugin (C#)..., or New C# Plugin... in the Plugin Manager.
- Type a name, for example
Level Tools. - Keep In project (the plugin lives in
<project>/Plugins/LevelTools/and travels with the project) and Start from: Blank. - Press Create.
The editor writes the plugin folder, enables the plugin for the project, builds it (a Build C# plugin task in the Tasks panel) and loads it. No restart: its panel, Level Tools, opens, and the folder opens in your code editor.
LevelTools/
LevelTools/ LevelTools.kplugin the manifest: id, version, what the plugin may use LevelTools.csproj the C# project (references KroysPlugins.Sdk.dll) Plugin.cs your code .vscode/ attach-debugger and build settings for VS Code
Draw a panel
A plugin is one class derived from EditorPlugin. In OnLoad it registers what it adds through Host; here a panel with a button and a counter.
The panel is drawn every frame it is visible (immediate mode): each ui.* call draws one control and returns true when the user clicked or changed it. Panels use the editor's own controls and theme, so a plugin looks like part of the editor.
Plugin.cs
public sealed class LevelToolsPlugin : EditorPlugin { private int clicks; public override void OnLoad() { Host.AddPanel(new PanelOptions("Main", "Level Tools") { Icon = "plug" }, DrawPanel); } private void DrawPanel(Ui ui) { ui.Heading("Level Tools"); if (ui.Button("Count", ButtonStyle.Primary)) clicks++; ui.SameLine(); ui.Text($"Clicks: {clicks}"); } }
Change it while it runs
Add a line to DrawPanel and save. The editor notices within half a second, builds the plugin in the background and hot-reloads it: the panel shows your change and keeps its place in the layout.
A reload removes every registration of the old build, calls OnUnload, unloads the old assembly and calls OnLoad on a new instance. Fields start fresh; values saved with Host.SetSetting stay.
Plugin.cs(14,9): error CS1002: ; expected; click it to jump to the line.Plugin.cs, edited
ui.Heading("Level Tools"); if (ui.Button("Count clicks", ButtonStyle.Primary)) clicks += 1; ui.SameLine(); ui.Text($"Clicks: {clicks}"); ui.Text("Hello from my first plugin!"); // saved: the editor rebuilds and reloads
Make a change you can undo
Commands appear in Tools › Plugins, in the command palette (Ctrl+Shift+P) and, with Toolbar = true, on the viewport's plugin toolbar. This one lifts the selected entities by one metre. Everything inside Host.Transaction is one undo step, named after the transaction, so Ctrl+Z reverts the whole command.
What a plugin may use is declared in its manifest. The blank template declares capability commands panels settings services tasks automation and permission scene.read scene.write; a call outside them fails with a message naming the line to add. See Manifest and permissions.
Plugin.cs
public override void OnLoad() { Host.AddPanel(new PanelOptions("Main", "Level Tools") { Icon = "plug" }, DrawPanel); Host.AddCommand(new CommandOptions("Lift", "Lift Selection") { Toolbar = true, Icon = "arrow-up", Shortcut = "Ctrl+Shift+L" }, Lift); } private void Lift() { World scene = Host.Document ?? throw new InvalidOperationException("Open a scene first."); using (Host.Transaction("Lift Selection")) // one undo step for the whole edit { foreach (Entity entity in Host.Selection) { Transform transform = scene.GetTransform(entity); transform.Position += new Vector3(0.0f, 1.0f, 0.0f); scene.SetTransform(entity, transform); } } }
Debug it
In VS Code, run Attach to Kroys Editor (.vscode/launch.json), set a breakpoint and use the plugin. Builds include symbols. After a reload, attach again if the debugger lost the old module.
Next: Panels and controls.
KroysEngine 0.1.0 documentation, built from the engine repository by Tools/BuildDocsSite.py.