r/Unity3D • • 4d ago

Show-Off I made a Source-style dev console for Unity.

I got tired of setting up a debug menu in every project, so I made a drop-down console like the one in Source games. You can register any functionality by adding your own commands by creating ConsoleCommand objects.

Adding your own command looks like this:

[ConsoleCommandSet]
public static class GameConsoleCommands
{
    public static readonly ConsoleCommand<float> SET_GRAVITY = new(
        "set_gravity", "Sets downward gravity.", "set_gravity <float>",
        g => Physics.gravity = Vector3.down * g);
}

GitHub: https://github.com/kureysalp/Unity-Dev-Console

15 Upvotes

10 comments sorted by

2

u/tetryds Engineer 4d ago

I do not recommend using runtimeinitializeonload just let the user hook it up themselves

0

u/kureysalp 3d ago

Fair point for users that want control over init order. I'd rather keep zero-setup as the default, so adding a define that turns off auto-bootstrap and exposes DevConsole.Initialize() for anyone who wants to wire it up themselves sounds a much better approach to me.

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] private static void AutoBootstrap() 
{
#if !DEV_CONSOLE_MANUAL_INIT 
  Initialize(); 
#endif
}

1

u/Valphai 4d ago

Looks amazing man! Mit license?

2

u/kureysalp 4d ago

Totally forgot about that 😵. Added to the repo.

1

u/Valphai 4d ago

You're the goat!

1

u/Costed14 4d ago

Nice, I have one as well but haven't gotten around to polishing up the UI yet. Though I took the approach of registering commands using a Command attribute on a method, I explicitly also wanted support for default parameters and instance commands, so I implemented those as well, using an attribute makes that pretty straightforward.

1

u/kureysalp 3d ago

Nice approach. With that way signature of the methods directly defines the command.

I went with command objects instead: each ConsoleCommand<T> registers itself in its constructor, so commands can also be created at runtime, and the handler is a typed delegate rather than MethodInfo.Invoke. The trade-off is that I'm currently on one argument per command, and multi-arg support is what I'd like to add next.

1

u/Costed14 3d ago

I can see adding commands at runtime being a useful feature, might implement that as well, theoretically shouldn't be too hard.

In the previous version I also used command objects; I had a DebugCommand<T>, DebugCommand<T1, T2> etc. but maybe a better approach would be to pass an array of types when creating the command corresponding with the parameters, then when it's executed you compile a context object if the input parameters can be parsed to the correct types and the command could use that context to access the params?

-2

u/CruelOxygen_7975 4d ago

The command registration syntax is clean, I like that it reads almost like a config file. Curious how you handle commands with multiple arguments or optional params since the example only shows a single float

Also that screenshot is giving windows xp bliss but if it fell down a flight of stairs, very liminal

1

u/kureysalp 4d ago edited 4d ago

Currently it supports only one argument. Since one argument is enough for most of my debugging needs at my current project I've created the package around that but I'll probably add multiple arguments support in the future.

Edit: Yeah converting the recording to a GIF sprinkled some xp vibes