Skip to content

About

Attribute-based in-game command terminal for Unity. Supports static & instance methods, custom argument parsing, and context-aware auto-completion.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

UniTerminal

Release License Unity

Setup

Use the menu to create and add the Developer Console prefab to your scene:

  • Assets → Create → UniTerminal → UniTerminal
  • Tools → UniTerminal → Create UniTerminal Prefab

This will create a prefab variant in the folder currently open in the Project window.

Command Parameters

When defining commands, methods can have the following parameters:

1. Response callback (optional)

Action<string> response        // Receives console messages
Action<string, bool> response  // Receives message + success/failure
CommandResponseDelegate response // Receives message + optional success/failure
  • string = message to log
  • bool = whether the command succeeded

Example:

[ConsoleCommand("heal", "Heals the player.")]
public static void HealCommand(Action<string, bool> response, int amount)
{
    if (amount < 0) {
        response("Amount cannot be negative!", false); // Command did not succeed - logs as an error (red)
        return;
    }
    Player.Instance.Heal(amount);
    response($"Healed player for {amount} HP", true); // Command succeeded - logs normally
}

2. Arguments

UniTerminal supports a wide range of argument types, with automatic type conversion from strings:

Type Description Example Input
string Any text. Use quotes if it contains spaces. "Hello world"
int Integer numbers. 42
float Decimal numbers. 3.14
bool True or false. true / false
enum Any enum type. Matches enum names (case-insensitive). MoveMode.Walk
Vector2 2D vector (x,y) format. (1.0,2.5)
Vector3 3D vector (x,y,z) format. (0,1,0)
Color RGBA color (r,g,b,a) format. (1,0,0,1) for opaque red
Quaternion Rotation (x,y,z,w) format. (0,0,0,1)

Notes

  • Default values: Arguments can have defaults if omitted:
[ConsoleCommand("screenshot", "Takes a screenshot.")]
public static void ScreenshotCommand(Action<string> response, string filename = "screenshot.png")
{
    ScreenCapture.CaptureScreenshot(filename);
    response($"Saved screenshot as {filename}", true);
}
  • Multiple arguments: Separate with spaces. Strings containing spaces must be quoted:
spawnEnemy "Big Slime" (0,1,0) true
  • Type conversion: UniTerminal automatically converts argument strings to the required type. Errors are logged if conversion fails.

  • Nullable types: Nullable parameters are supported, e.g., int?, float?.

  • Custom argument types: You can register your own converters for custom types. For example, the built-in Vector3 converter:

UniTerminal.RegisterArgConverter<Vector3>(arg =>
{
    var parts = arg.Trim('(', ')').Split(',');
    if (parts.Length != 3)
        throw new ArgumentException($"Could not convert '{arg}' to Vector3");

    return new Vector3(
        float.Parse(parts[0]),
        float.Parse(parts[1]),
        float.Parse(parts[2])
    );
});

Once registered, UniTerminal will automatically convert arguments of that type when invoking commands.


3. Command Execution

Commands are invoked by typing in the console:

<command> [arg1] [arg2] ...
  • The first parameter can optionally be a response callback (Action<string> or Action<string, bool>).
  • Remaining parameters are parsed and converted automatically.
  • Quoted strings are supported: "Hello World".
  • Errors such as missing or invalid arguments are automatically logged to the console.

4. Chained Commands

Multiple commands can be executed in a single line using the |(configurable) separator:

command1 arg1 | command2 arg2 arg3

Each command runs sequentially, and errors in one command do not prevent subsequent commands from executing.


5. Command Flags

Commands can include flags to control when and how they are available. Flags are optional and can be combined using the bitwise OR operator (|).

Flag Description
None No special behavior. Command is always available.
DebugOnly Command is only available in debug builds. Cannot be combined with EditorOnly.
EditorOnly Command is only available in the Unity editor. Cannot be combined with DebugOnly.
Cheat Marks the command as a cheat. Only runs if CheatsEnabled is true.
Mod Command is added by a mod or external plugin.
Hidden Command is hidden from help listings, but can still be invoked.

Editor commands: AllowInEditor is not a flag — it is a separate opt-in property on [ConsoleCommand] (see section 10). EditorOnly means "editor builds + editor playmode". AllowInEditor = true means "also runnable in edit mode (not playing) via the editor command window".

Cheat Commands Note:

  • UniTerminal includes a built-in enablecheats command to toggle cheat commands globally.
  • Alternatively, you can disable the built-in command and provide your own mechanism for enabling cheats by setting UniTerminal.CheatsEnabled manually.
  • Commands with the Cheat flag will only run if CheatsEnabled is true.

Example:

[ConsoleCommand("godMode", "Enables invincibility.", CommandFlags.Cheat | CommandFlags.DebugOnly)]
public static void GodModeCommand(Action<string> response)
{
    Player.Instance.Invincible = true;
    response("God mode enabled!", true);
}

Here is the updated section 6, expanded to include the new functionality for registering auto-complete methods.


6. Auto-completion & Suggestions

UniTerminal supports tab-based auto-completion for both command names and argument values.

  • Command Names: Unmatched text is automatically completed against registered commands (case-insensitive).
  • Built-in Types: Arguments of type bool (true/false) and enum are automatically auto-completed.

Custom Argument Suggestions

Suggestions are configured per parameter with attributes. On Tab, UniTerminal tries them in order: [SuggestValues] / [Suggest] → code-registered providers (below) → built-in bool / enum handling. Providers return candidates; UniTerminal filters and sorts them by your input, so every signature behaves the same.

Attribute Use
[SuggestValues("a", "b")] Fixed list. Works on any parameter type.
[Suggest(nameof(MyMethod))] Static method in the same class: () or (AutoCompleteContext), returning IEnumerable<string>.
[Suggest(typeof(Shared), nameof(Shared.Method))] Same, but shared across classes via a compile-time type reference.

AutoCompleteContext carries Prefix, ArgIndex (as typed by the user — a leading Action<string> response callback is skipped), ParamName, and TypedArgs.


Examples

1. Fixed list

[ConsoleCommand("coins", Description = "Grants coins.")]
public static void CoinsCommand(Action<string, bool> response, [SuggestValues("50", "250", "1000", "5000")] int amount = 250)
{ ... }

2. Shared provider

[ConsoleCommand("give", Description = "Give item.")]
public static void GiveCommand(Action<string> reply,
    [Suggest(typeof(Players), nameof(Players.Suggest))] string target,
    [SuggestValues("Sword", "Shield")] string item)
{ ... }

static class Players
{
    public static IEnumerable<string> Suggest(AutoCompleteContext ctx) => AllPlayers;
}

Code-registered providers (lambdas)

Attributes can't hold lambdas, so functions closing over live game data are registered at startup:

UniTerminal.RegisterSuggestions<FoodId>(ctx => FoodDb.AllNames); // every FoodId param
UniTerminal.RegisterSuggestions("give", "item", ctx => ItemDb.FindMatches(ctx.Prefix)); // one param

Unregister with UnregisterSuggestions<T>() / UnregisterSuggestions(command, param), or wipe with ClearRegisteredSuggestions().

Legacy providers (obsolete)

AutoCompleteProvider = nameof(Method) on [ConsoleCommand] still works: one static provider per command with ( )/int/string/string+int signatures, where the string variants must filter themselves and multi-arg commands switch on index. Migrate to per-parameter attributes when you touch those commands.

Note: If a suggestion contains spaces (e.g., "Big Slime"), UniTerminal will automatically wrap it in quotes when selected.


7. Performance & Caching

UniTerminal is designed for zero startup overhead. Unlike traditional consoles that scan your assemblies using Reflection every time the game starts (causing lag), UniTerminal pre-calculates and caches command metadata in the Unity Editor.

When does the cache update?

  1. Automatically: The cache is rebuilt automatically whenever you modify your scripts and trigger a Recompile / Domain Reload.
  2. Manually: If for any reason the cache seems out of sync, you can force a rebuild via the menu:
    • Tools → UniTerminal → Manual Build Command Cache

What this means for you:

  • Editor: You simply write code. Commands appear in the console immediately after compilation.
  • Builds: The cached data is serialized into the build. The game launches with 0ms reflection cost for command discovery.

Troubleshooting: If you just added a [ConsoleCommand] but it's not showing up in autocomplete, ensure your scripts have finished compiling. If it still persists, click Manual Build Command Cache.


8. Configuration & Settings

You can configure UniTerminal's behavior via the dedicated settings window. These settings allow you to strip out built-in features to keep your builds lightweight or adjust the editor workflow.

Open the settings window:

  • Tools → UniTerminal → UniTerminal Window

Runtime & Editor Settings

These settings modify the Scripting Define Symbols of your project. Changing them will trigger a script recompilation.

Setting Description
Include Built-In Commands If enabled, includes additional utility commands (e.g. time scale or system info).

Note: The core commands help, clear, and toggleUnityLogs are essential to the system and are always included, regardless of this setting.
Include Built-In Cheat Command If enabled, the enablecheats command is available. Disable this for release builds if you want to prevent users from easily toggling cheat mode (or if you want to implement your own cheat logic).
Include Built-In Editor Commands (2.7+) If enabled, ships pre-built editor commands (saveall, play, settings, … — see section 10). Editor-assembly only, so they can never ship in builds.

Editor Workflow

These settings only affect the Unity Editor environment and are saved in EditorPrefs.

Setting Description
Auto Rebuild Cache (Recommended: On) Automatically updates the command cache whenever scripts are compiled. If you have a very large project with slow iteration times, you can turn this off and manually rebuild the cache only when needed.
Detailed Logging If enabled, UniTerminal will log a change report to the Unity Console after a cache rebuild, detailing exactly which commands were Added, Removed, or Modified. Useful for verifying that your code changes were detected correctly.

Manual Actions

  • Manual Rebuild Command Cache: Forces a rebuild via Unity's indexed TypeCache and rewrites the command database. Use this if the console isn't picking up a new [ConsoleCommand] attribute immediately.

9. Runtime Assembly Discovery (Mods & DLC)

Since UniTerminal caches commands at build time, any code loaded dynamically after the game starts (such as Mods, DLCs, or Addressables) will not be in the initial cache. You must manually tell UniTerminal to scan these new assemblies.

How to register an assembly

Use UniTerminal.DiscoverCommandsInAssembly() to scan a specific assembly for [ConsoleCommand] attributes.

Example 1: Self-Registering Mod If you are building a mod (e.g., for BepInEx), you can have the mod register itself when it loads.

using System.Reflection;
using UnityEngine;
using NoSlimes.Util.UniTerminal;

public class MyMod : MonoBehaviour
{
    private void Awake()
    {
        // Tells UniTerminal to scan THIS assembly for commands immediately
        UniTerminal.DiscoverCommandsInAssembly(Assembly.GetExecutingAssembly());
        
        Debug.Log("MyMod commands registered!");
    }

    [ConsoleCommand("mod_hello", "Says hello from the mod.")]
    public static void HelloCommand()
    {
        Debug.Log("Hello from MyMod!");
    }
}

Example 2: External Mod Loader If you have a dedicated ModLoader script that loads DLLs from a folder:

public void LoadMod(string path)
{
    // Load the DLL
    Assembly modAssembly = Assembly.LoadFrom(path);

    // Register its commands into the console
    UniTerminal.DiscoverCommandsInAssembly(modAssembly);
}

Note: Do not call this for your main game assembly (Assembly-CSharp) if you are using the default setup, as those commands are already optimized and cached. This method is specifically for code loaded after the game has started.


10. Editor Commands (AllowInEditor) & Command Window

As of 2.6, UniTerminal commands can also run in the Unity Editor without entering playmode, e.g. for scene/asset tooling, validation, batch operations, or spawning test content.

Open the window via Tools → UniTerminal → Command Window.

Opting in

Add AllowInEditor = true to the attribute. It is opt-in (default false), orthogonal to CommandFlags:

[ConsoleCommand("spawn_test_cube", Description = "Spawns a test cube in the scene.", AllowInEditor = true)]
public static void SpawnTestCube(Action<string> response)
{
    var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
    Undo.RegisterCreatedObjectUndo(cube, "Spawn test cube");
    response("Spawned test cube.");
}

Safety: commands that modify scenes or assets should handle Undo and dirty marking themselves (e.g. Undo.RegisterCreatedObjectUndo, EditorUtility.SetDirty, EditorSceneManager.MarkSceneDirty). The command window groups each run in an Undo group, but static modifications are only undoable if the command registers them.

About

Attribute-based in-game command terminal for Unity. Supports static & instance methods, custom argument parsing, and context-aware auto-completion.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages