[Released] Console Toolbox

Console Toolbox is an all in one console and development tools suite. Simply drop the console into your existing project to start using its built in commands, then expand your toolbox with the click of a button!

Features:

  • Quake style console
  • TextMesh Pro GUI
  • New command editor/generator
  • Unity log/trace

Built In Commands:

  • entity: suite of entity/scene hierarchy tools
  • scene: suite of scene management tools
  • help: describes all commands
  • log: toggle Unity log output
  • writelogs: write all console output to file

Entity tools can output the current scene hierarchy to the console with optional entity filtering capabilities, allow you to call any function, check or modify a property value on an entity, and visually select entities.

Scene tools provide a suite of commands to load and unload scenes (with options for additive and async), activate scenes, and list currently loaded scenes or available scenes.

Also includes console variable capabilities and full source code!

AssetStore | Website | Community Git

Hey, logs with stacktraces would be helpful when exceptions are thrown.

2 Likes

Hey Andreas0,

Thanks for pointing that out - bit of an oversight on my part, I’m storing the trace in the logs but forgot to display them. Now that I’m looking into it I see that a trace level might also be useful, since all Unity debug callbacks are sent with a trace. I’ll update this when I’ve submitted a solution to the asset store.

Thanks again.

Great :slight_smile:

Ok I’ve submitted version 1.1 to the asset store for all versions. Traces will display in the console and when writing the output to a log file. I’ve also replaced OutputStackTrace with OutputTraceLevel, which allows you to choose a trace level for unity output.

Levels are:
None: No stack traces
Low: Only Exception and Assert traces
Medium: Exception, Assert, and Error traces
High: Exception, Assert, Error, and Warning traces
All: Exception, Assert, Error, Warning, and Log traces

More information can be found in the docs.

Version 1.2 is available on the asset store.

This version has been tested with the latest version of Unity (2019.2.9f1) and includes to following fixes:

-fixed console output only displaying one item in builds
-fixed cursor position when auto-completing commands
-console now automatically adds an event system if not present

Is it usable on mobile ? (virtual keyboard, and scroll on touch)

@jojo2K I have not developed any mobile apps but according to Unity’s documentation Unity - Manual: Mobile Keyboard it should appear and work correctly when interacting with the terminal, which uses TextMeshPro InputField.

Scrolling is handled with pageUp/pageDown.

I am getting an error about the new unity input system. Is this compatible?

I think I might have fixed it by replacing all the Input and KeyCodes with the new input system in the Terminal.cs and Console.cs. I haven’t tested it fully, and for some reason in Console.cs to Terminal.cs the toggleFullModifier value changes, but other wise it seems to be working great.

A good adition would be to add #if USE_NEW_INPUT to the code

Hey there,

Sorry about that, I haven’t had the chance to update this asset now that the new input system is official. The easy way to use it would be to enable both the old and new systems:

Edit->Project Settings->Player->Other Settings->Active Input Handling->Both

Otherwise, you’ll need to update Console.cs and Terminal.cs with the following, as well as reassigning the hotkeys in the prefab:

Console.cs

#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif

        [Header("Hotkeys")]
#if ENABLE_INPUT_SYSTEM
        [SerializeField]
        public Key ToggleHotkey = Key.Backquote;
        [SerializeField]
        private Key ToggleFullModifier = Key.LeftShift;
        [SerializeField]
        private Key ToggleFullHotkey = Key.Backquote;
#else
        [SerializeField]
        public KeyCode ToggleHotkey = KeyCode.BackQuote;
        [SerializeField]
        private KeyCode ToggleFullModifier = KeyCode.LeftShift;
        [SerializeField]
        private KeyCode ToggleFullHotkey = KeyCode.BackQuote;
#endif

        protected override void Awake()
        {
            base.Awake();

            if( Console.Exists() )
            {
#if ENABLE_INPUT_SYSTEM
                Assert.AreNotEqual( ToggleHotkey, Key.Enter, "Return is not a valid ToggleHotkey" );
                Assert.AreNotEqual( ToggleHotkey, Key.Escape, "Escape is not a valid ToggleHotkey" );
                Assert.AreNotEqual( ToggleHotkey, Key.Tab, "Tab is not a valid ToggleHotkey" );
#else
                Assert.AreNotEqual( ToggleHotkey, KeyCode.Return, "Return is not a valid ToggleHotkey" );
                Assert.AreNotEqual( ToggleHotkey, KeyCode.Escape, "Escape is not a valid ToggleHotkey" );
                Assert.AreNotEqual( ToggleHotkey, KeyCode.Tab, "Tab is not a valid ToggleHotkey" );
#endif
            }
        }

Terminal.cs

#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif

#if ENABLE_INPUT_SYSTEM
        public Key toggleHotkey { get; set; }
        public Key toggleFullHotkey { get; set; }
        public Key toggleFullModifier { get; set; }
#else
        public KeyCode toggleHotkey { get; set; }
        public KeyCode toggleFullHotkey { get; set; }
        public KeyCode toggleFullModifier { get; set; }
#endif

 private void LateUpdate()
        {
#if ENABLE_INPUT_SYSTEM
            var keyboard = Keyboard.current;

            if( keyboard[toggleFullModifier].isPressed &&
                keyboard[toggleFullHotkey].wasPressedThisFrame )
            {
                if( GUI.activeSelf == false )
                    return;

                SetState( TerminalState.OpenLarge );

                return;
            }

            if( keyboard[Key.PageDown].isPressed )
            {
                GUIScrollView.verticalNormalizedPosition -= ScrollSpeed;

                return;
            }

            if( keyboard[Key.PageUp].isPressed )
            {
                GUIScrollView.verticalNormalizedPosition += ScrollSpeed;

                return;
            }

            if( keyboard.anyKey.wasPressedThisFrame == false )
                return;

            if( keyboard[toggleHotkey].wasPressedThisFrame )
            {
                if( GUI.activeSelf == false )
                {
                    GUI.SetActive( true );

                    onTerminalOpened.Invoke();
                }

                SetState( TerminalState.OpenSmall );

                return;
            }

            if( keyboard[Key.Tab].wasPressedThisFrame )
            {
                CompleteCommand();

                return;
            }

            if( keyboard[toggleHotkey].wasPressedThisFrame )
            {
                SetState( TerminalState.OpenSmall );

                return;
            }

            if( keyboard[Key.UpArrow].wasPressedThisFrame )
            {
                GUIInput.text = History.Previous();

                GUIInput.MoveTextEnd( false );

                return;
            }

            if( keyboard[Key.DownArrow].wasPressedThisFrame )
            {
                GUIInput.text = History.Next();

                GUIInput.MoveTextEnd( false );

                return;
            }

            if( GUI.activeSelf == true )
                GUIInput.ActivateInputField();

#else
            if( Input.GetKey( toggleFullModifier ) && Input.GetKeyDown( toggleFullHotkey ) )
            {
                if( GUI.activeSelf == false )
                    return;

                SetState( TerminalState.OpenLarge );

                return;
            }

            if( Input.GetKey( KeyCode.PageDown ) )
            {
                GUIScrollView.verticalNormalizedPosition -= ScrollSpeed;

                return;
            }

            if( Input.GetKey( KeyCode.PageUp ) )
            {
                GUIScrollView.verticalNormalizedPosition += ScrollSpeed;

                return;
            }

            if( Input.anyKeyDown == false )
                return;

            if( Input.GetKeyDown( toggleHotkey ) )
            {
                if( GUI.activeSelf == false )
                {
                    GUI.SetActive( true );

                    onTerminalOpened.Invoke();
                }

                SetState( TerminalState.OpenSmall );

                return;
            }

            if( Input.GetKeyDown( KeyCode.Tab ) )
            {
                CompleteCommand();

                return;
            }

            if( Input.GetKeyDown( toggleHotkey ) )
            {
                SetState( TerminalState.OpenSmall );

                return;
            }

            if( Input.GetKeyDown( KeyCode.UpArrow ) )
            {
                GUIInput.text = History.Previous();

                GUIInput.MoveTextEnd( false );

                return;
            }

            if( Input.GetKeyDown( KeyCode.DownArrow ) )
            {
                GUIInput.text = History.Next();

                GUIInput.MoveTextEnd( false );

                return;
            }

            if( GUI.activeSelf == true )
                GUIInput.ActivateInputField();
#endif
     }

An updated version has been published to the asset store that works with the new input system.