Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple, easy-to-use console for Unity.
using System;
[AttributeUsage(AttributeTargets.Method)]
public class ConsoleAccessAttribute : Attribute
{
}
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
public static class EasyConsole
{
private static readonly Dictionary<string, MethodInfo> allMethods = new Dictionary<string, MethodInfo>();
private static readonly List<string> searchResults = new List<string>();
[RuntimeInitializeOnLoadMethod]
private static void Initialize()
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
const BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
foreach (var assembly in assemblies)
{
var types = assembly.GetTypes();
foreach (var type in types)
{
var methods = type.GetMethods(bindingFlags).Where(method => Attribute.IsDefined(method, typeof(ConsoleAccessAttribute)));
foreach (var method in methods)
{
allMethods.Add(method.Name.ToLower(), method);
}
}
}
}
public static bool TryRunCommand(string command, params string[] parameters)
{
command = command.ToLower();
if (allMethods.TryGetValue(command, out var methodInfo))
{
try
{
var parameterInfos = methodInfo.GetParameters();
if (parameterInfos.Length == 0)
{
methodInfo.Invoke(null, null);
}
else if (parameterInfos.Length == 1 && parameterInfos[0].ParameterType == typeof(string[]))
{
methodInfo.Invoke(null, new string[][] { parameters });
}
else
{
if (parameters.Length == parameterInfos.Length)
{
var castParameters = new object[parameters.Length];
for (var i = 0; i < parameters.Length; i++)
{
castParameters[i] = Convert.ChangeType(parameters[i], parameterInfos[i].ParameterType);
}
methodInfo.Invoke(null, castParameters);
}
else
{
return false;
}
}
return true;
}
catch { }
}
return false;
}
public static bool TryRunCommand(string[] parts)
{
var command = parts[0];
var parameters = new string[parts.Length - 1];
Array.Copy(parts, 1, parameters, 0, parameters.Length);
return TryRunCommand(command, parameters);
}
public static IEnumerable<string> GetMethodsContaining(string s)
{
searchResults.Clear();
s = s.ToLower();
foreach (var kvp in allMethods)
{
var name = kvp.Key;
if (name.Contains(s))
{
searchResults.Add(kvp.Value.Name);
}
}
return searchResults.AsReadOnly();
}
}
using UnityEngine;
using System;
using System.Collections.Generic;
public class EasyConsoleTest : MonoBehaviour
{
private string previousCommand = "";
private string content = "";
private IEnumerable<string> searchResults;
private void OnGUI()
{
content = GUILayout.TextField(content, GUILayout.Width(500));
if (!string.IsNullOrEmpty(content))
{
var parts = content.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var command = parts[0];
if (Event.current.isKey && Event.current.keyCode == KeyCode.Return)
{
var success = EasyConsole.TryRunCommand(parts);
if (!success)
{
Debug.Log("Could not call method.");
}
content = "";
}
if (command != previousCommand)
{
searchResults = EasyConsole.GetMethodsContaining(command);
}
foreach (var searchResult in searchResults)
{
if (GUILayout.Button(searchResult))
{
content = searchResult;
}
}
previousCommand = command;
}
}
[ConsoleAccess]
private static void Print(string[] parameters)
{
Debug.Log(string.Join(" ", parameters));
}
[ConsoleAccess]
private static void Kill()
{
Debug.Log("The player died.");
}
[ConsoleAccess]
private static void AddPoints(int amount)
{
Debug.Log("Adding " + amount + " points.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.