Repository: mikelovesrobots/unity3d-console Branch: master Commit: 398b03654f4c Files: 24 Total size: 15.3 KB Directory structure: gitextract_fpc9hxd9/ ├── Console/ │ ├── Prefabs/ │ │ ├── Console.prefab │ │ └── Console.prefab.meta │ ├── Prefabs.meta │ ├── Scripts/ │ │ ├── ConsoleAction.cs │ │ ├── ConsoleAction.cs.meta │ │ ├── ConsoleCloseAction.cs │ │ ├── ConsoleCloseAction.cs.meta │ │ ├── ConsoleCommandsRepository.cs │ │ ├── ConsoleCommandsRepository.cs.meta │ │ ├── ConsoleGUI.cs │ │ ├── ConsoleGUI.cs.meta │ │ ├── ConsoleLog.cs │ │ ├── ConsoleLog.cs.meta │ │ ├── ConsoleNamedKeyBugFix.cs │ │ ├── ConsoleNamedKeyBugFix.cs.meta │ │ ├── ConsoleOpenAction.cs │ │ ├── ConsoleOpenAction.cs.meta │ │ ├── ConsoleSubmitAction.cs │ │ ├── ConsoleSubmitAction.cs.meta │ │ ├── ConsoleToggler.cs │ │ └── ConsoleToggler.cs.meta │ └── Scripts.meta ├── LICENSE-BSD3 └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: Console/Prefabs/Console.prefab.meta ================================================ fileFormatVersion: 2 guid: 2cea168450a79486e94c931fe953714a NativeFormatImporter: userData: ================================================ FILE: Console/Prefabs.meta ================================================ fileFormatVersion: 2 guid: 3db4c15f837a44329ad26908c4c96ba0 DefaultImporter: userData: ================================================ FILE: Console/Scripts/ConsoleAction.cs ================================================ using UnityEngine; using System.Collections; public abstract class ConsoleAction : MonoBehaviour { public abstract void Activate(); } ================================================ FILE: Console/Scripts/ConsoleAction.cs.meta ================================================ fileFormatVersion: 2 guid: fd9cfafa8b0064c8a8817864e0bd14c3 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Console/Scripts/ConsoleCloseAction.cs ================================================ using UnityEngine; using System.Collections; public class ConsoleCloseAction : ConsoleAction { public GameObject ConsoleGui; public override void Activate() { #if UNITY_3_5 ConsoleGui.active = false; #else ConsoleGui.SetActive(false); #endif } } ================================================ FILE: Console/Scripts/ConsoleCloseAction.cs.meta ================================================ fileFormatVersion: 2 guid: 419193451d58c4af783629ccaaaed791 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Console/Scripts/ConsoleCommandsRepository.cs ================================================ using UnityEngine; using System.Collections; using System.Collections.Generic; public delegate string ConsoleCommandCallback(params string[] args); public class ConsoleCommandsRepository { private static ConsoleCommandsRepository instance; private Dictionary repository; public static ConsoleCommandsRepository Instance { get { if (instance == null) { instance = new ConsoleCommandsRepository(); } return instance; } } public ConsoleCommandsRepository() { repository = new Dictionary(); } public void RegisterCommand(string command, ConsoleCommandCallback callback) { repository[command] = new ConsoleCommandCallback(callback); } public bool HasCommand(string command) { return repository.ContainsKey(command); } public List SearchCommands(string str) { string[] keys = new string[repository.Count]; repository.Keys.CopyTo(keys, 0); List output = new List(); foreach (string key in keys) { if (key.StartsWith(str)) output.Add(key); } return output; } public string ExecuteCommand(string command, string[] args) { if (HasCommand(command)) { return repository[command](args); } else { return "Command not found"; } } } ================================================ FILE: Console/Scripts/ConsoleCommandsRepository.cs.meta ================================================ fileFormatVersion: 2 guid: bfa76a4e55fcc44f5b433808cdcba7c0 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Console/Scripts/ConsoleGUI.cs ================================================ using UnityEngine; using System.Collections; using System.Collections.Generic; public class ConsoleGUI : MonoBehaviour { public ConsoleAction escapeAction; public ConsoleAction submitAction; [HideInInspector] public string input = ""; private ConsoleLog consoleLog; private Rect consoleRect; private bool focus = false; private const int WINDOW_ID = 50; private const int MIN_CONSOLE_HEIGHT = 300; private ConsoleCommandsRepository consoleCommandsRepository; private int maxConsoleHistorySize = 100; private int consoleHistoryPosition = 0; private List consoleHistoryCommands = new List(); private bool fixPositionNextFrame = false; // a hack because the up arrow moves the cursor to the first position. private float scrollPosition; private void Start() { consoleRect = new Rect(0, 0, Screen.width, Mathf.Min(MIN_CONSOLE_HEIGHT, Screen.height)); consoleLog = ConsoleLog.Instance; consoleCommandsRepository = ConsoleCommandsRepository.Instance; } private void OnEnable() { focus = true; } private void OnDisable() { focus = true; } public void OnGUI() { GUILayout.Window(WINDOW_ID, consoleRect, RenderWindow, "Console"); } private void RenderWindow(int id) { if (fixPositionNextFrame) { MoveCursorToPos(input.Length); fixPositionNextFrame = false; } HandleSubmit(); HandleEscape(); HandleTab(); HandleUp(); HandleDown(); scrollPosition = GUILayout.BeginScrollView(new Vector2(0, scrollPosition), false, true).y; if (consoleLog.fresh) { scrollPosition = consoleLog.scrollLength; consoleLog.fresh = false; } GUILayout.Label(consoleLog.log); GUILayout.EndScrollView(); GUI.SetNextControlName("input"); input = GUILayout.TextField(input); if (focus) { GUI.FocusControl("input"); focus = false; } } private string LargestSubString(string in1, string in2) // takes two strings and returns the largest matching substring. { string output = ""; int smallestLen = Mathf.Min(in1.Length, in2.Length); for (int i = 0; i search = consoleCommandsRepository.SearchCommands(input); if (search.Count == 0) { // nothing found consoleLog.Log("No commands start with \"" + input + "\"."); input = ""; // clear input } else if (search.Count == 1) { input = search[0] + " "; // only found one command - type it in for the guy MoveCursorToPos(input.Length); } else { consoleLog.Log("Commands starting with \"" + input + "\":"); string largestMatch = search[0]; // keep track of the largest substring that matches all searches foreach (string command in search) { consoleLog.Log(command); largestMatch = LargestSubString(largestMatch, command); } input = largestMatch; MoveCursorToPos(input.Length); } } } private void HandleUp() { if (!KeyDown("up")) return; consoleHistoryPosition += 1; if (consoleHistoryPosition > consoleHistoryCommands.Count - 1) consoleHistoryPosition = consoleHistoryCommands.Count - 1; input = consoleHistoryCommands[consoleHistoryPosition]; fixPositionNextFrame = true; } private void HandleDown() { if (!KeyDown("down")) return; consoleHistoryPosition -= 1; if (consoleHistoryPosition < 0) { consoleHistoryPosition = -1; input = ""; } else { input = consoleHistoryCommands[consoleHistoryPosition]; } MoveCursorToPos(input.Length); } private void HandleSubmit() { if (KeyDown("[enter]") || KeyDown("return")) { consoleHistoryPosition = -1; // up arrow or down arrow will set it to 0, which is the last command typed. if (submitAction != null) { submitAction.Activate(); consoleHistoryCommands.Insert(0, input); if (consoleHistoryCommands.Count > maxConsoleHistorySize) consoleHistoryCommands.RemoveAt(consoleHistoryCommands.Count-1); } input = ""; } } private void HandleEscape() { if (KeyDown("escape") || KeyDown("`")) { escapeAction.Activate(); input = ""; } } private void Update() { if (input == "`") input = ""; } private bool KeyDown(string key) { return Event.current.Equals(Event.KeyboardEvent(key)); } } ================================================ FILE: Console/Scripts/ConsoleGUI.cs.meta ================================================ fileFormatVersion: 2 guid: 6343eab7608084fc1b94a45956d6d979 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Console/Scripts/ConsoleLog.cs ================================================ using UnityEngine; using System.Collections; public class ConsoleLog { private static ConsoleLog instance; public static ConsoleLog Instance { get { if (instance == null) { instance = new ConsoleLog(); } return instance; } } public string log = ""; public int scrollLength; public bool fresh = false; public void Log(string message) { log += message + "\n"; fresh = true; scrollLength += ((message+"\n").Split('\n').Length)*20; } } ================================================ FILE: Console/Scripts/ConsoleLog.cs.meta ================================================ fileFormatVersion: 2 guid: a145fe0fa0167487a8daabd42214525f MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Console/Scripts/ConsoleNamedKeyBugFix.cs ================================================ using UnityEngine; using System.Collections; public class ConsoleNamedKeyBugFix : MonoBehaviour { // Fixes the annoying issue described here: http://forum.unity3d.com/threads/158676-!dest-m_MultiFrameGUIState-m_NamedKeyControlList/page2 // seems to happen because ConsoleGUI creates and destroys a GUI textfield and the GUI doesn't know what to give focus to void OnGUI() { string controlName = gameObject.GetHashCode().ToString(); GUI.SetNextControlName(controlName); Rect bounds = new Rect(0,0,0,0); GUI.TextField(bounds, "", 0); } } ================================================ FILE: Console/Scripts/ConsoleNamedKeyBugFix.cs.meta ================================================ fileFormatVersion: 2 guid: d3f4095ae1a304e3c9d991cff6b4fa91 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Console/Scripts/ConsoleOpenAction.cs ================================================ using UnityEngine; using System.Collections; public class ConsoleOpenAction : ConsoleAction { public GameObject ConsoleGui; public override void Activate() { #if UNITY_3_5 ConsoleGui.active = false; #else ConsoleGui.SetActive(true); #endif } } ================================================ FILE: Console/Scripts/ConsoleOpenAction.cs.meta ================================================ fileFormatVersion: 2 guid: d3adb20f905ec4e0cba1b4b2bb0bdae3 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Console/Scripts/ConsoleSubmitAction.cs ================================================ using UnityEngine; using System; using System.Linq; using System.Collections; public class ConsoleSubmitAction : ConsoleAction { public ConsoleGUI consoleGUI; private ConsoleCommandsRepository consoleCommandsRepository; private ConsoleLog consoleLog; private void Start() { consoleCommandsRepository = ConsoleCommandsRepository.Instance; consoleLog = ConsoleLog.Instance; } public override void Activate() { string[] parts = consoleGUI.input.Split(' '); string command = parts[0]; string[] args = parts.Skip(1).ToArray(); consoleLog.Log("> " + consoleGUI.input); if (consoleCommandsRepository.HasCommand(command)) { consoleLog.Log(consoleCommandsRepository.ExecuteCommand(command, args)); } else { consoleLog.Log("Command " + command + " not found"); } } } ================================================ FILE: Console/Scripts/ConsoleSubmitAction.cs.meta ================================================ fileFormatVersion: 2 guid: fa9f5280ec96544eea9471171eb212e7 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Console/Scripts/ConsoleToggler.cs ================================================ using UnityEngine; using System.Collections; public class ConsoleToggler : MonoBehaviour { private bool consoleEnabled = false; public ConsoleAction ConsoleOpenAction; public ConsoleAction ConsoleCloseAction; void Update () { if (Input.GetKeyDown(KeyCode.BackQuote)) { ToggleConsole(); } } private void ToggleConsole() { consoleEnabled = !consoleEnabled; if (consoleEnabled) { ConsoleOpenAction.Activate(); } else { ConsoleCloseAction.Activate(); } } } ================================================ FILE: Console/Scripts/ConsoleToggler.cs.meta ================================================ fileFormatVersion: 2 guid: 8f0a035122d8f4a75a9dfcfcb6ada8c7 MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: ================================================ FILE: Console/Scripts.meta ================================================ fileFormatVersion: 2 guid: 3a383d72159054bb49ae80a8c805473b DefaultImporter: userData: ================================================ FILE: LICENSE-BSD3 ================================================ Copyright (c) 2013, Mike Judge All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================ In-game Console ======= Synopsis -------- Quake-style console plugin for Unity3d. Toggle the console by pressing tilde (~). Press tab to autocomplete commands. Screenshot ----------- ![Screenshot](https://dl.dropboxusercontent.com/s/z0gw0h267h0fzz4/Screen%20Shot%202014-01-06%20at%2011.26.19%20AM.png) Installation ------------ 1. Copy the Console directory to your Assets/Plugins folder. (Make the plugins folder if it doesn't exist.) 2. Drag the console prefab into your scene. 3. Run your scene and press ~ to launch the console. 4. Now register some custom commands Registering custom commands --------------- ``` using UnityEngine; using System.Collections; public class ConsoleCommandRouter : MonoBehaviour { void Start() { var repo = ConsoleCommandsRepository.Instance; repo.RegisterCommand("hi", Hi); repo.RegisterCommand("save", Save); repo.RegisterCommand("load", Load); } public string Hi(params string[] args) { return "Hey there yourself!"; } public string Save(params string[] args) { var filename = args[0]; // // [insert code here saving the game to that filename] // return "Saved to " + filename; } public string Load(params string[] args) { var filename = args[0]; // // [insert code here loading the game from that filename] // return "Loaded " + filename; } } ``` The string returned from the console command will be displayed to the in-game console log. Insert newlines in your response to have multiple lines be written to the log. Logging ------- ``` var logger = ConsoleLog.Instance; logger.Log("Player died") ``` Logs to the in-game console. Note from the author -------------------- Feel free to contribute your changes back! I love pull requests. Cheers, Mike mikelovesrobots@gmail.com @mikelovesrobots on Twitter