I’ve added a debug console to my game to allow for easy testing by, say, putting items into the player’s inventory. It can be toggled open/closed by typing a backtick (`). Unity refers to this as KeyCode.BackQuote. The problem I’m having is that when I open the console, the backtick character ends up in the input field, which I don’t want. I’ve tried to deal with this by using Event.current.Use() on all backtick events in OnGUI, but this doesn’t seem to help. The only solution I’ve come up with is to use a regex to strip out any backtick characters, but this feels like fighting the fire rather than dealing with the problem. Is there a more elegant way of keeping the backtick out of the input field?
Example C# code:
using System.Collections.Generic;
using UnityEngine;
using System.Collections;
using System.Text.RegularExpressions;
public class CommandConsole : MonoBehaviour
{
private Rect GuiRect;
public List<string> messages = new List<string>();
private string inputLine = ""; //This is where text entered into the console ends up.
private Vector2 scrollPos = Vector2.zero;
private Color textColour;
public float fadeoutTimer = 5.0f;
public float fadeSpeed = 0.5f;
private float inactiveTimer;
private GUIStyle labelStyle;
public void Start()
{
GuiRect = new Rect(0, 0, Screen.width, 300);
}
void OnGUI() {
//Uncomment this odd bit of code and the problem goes away
//if (Event.current.type == EventType.KeyDown && Event.current.keyCode==KeyCode.None) {
// Event.current.Use();
// return;
//}
if (Event.current.keyCode == KeyCode.BackQuote) {
if (Event.current.type == EventType.KeyDown) {
if (GUI.GetNameOfFocusedControl()=="ConsoleInput") {
GUI.FocusControl("");
}
else {
labelStyle = GUI.skin.label;
labelStyle.border = new RectOffset(0, 0, 0, 0);
labelStyle.margin = new RectOffset(0, 0, 0, 0);
labelStyle.padding = new RectOffset(4, 4, 1, 1);
GUI.FocusControl("ConsoleInput");
inactiveTimer = fadeoutTimer;
textColour = Color.white;
inputLine=""; //Reset this here
}
}
Event.current.Use(); //I was hoping this would fix it
return; //Returning early doesn't help either
}
else {
//Fade out the console if we're done with it.
if (GUI.GetNameOfFocusedControl() != "ConsoleInput") {
if (inactiveTimer <= 0.0f) {
if (textColour.a > 0.0f) {
textColour.a -= fadeSpeed * Time.deltaTime;
}
}
else {
inactiveTimer -= fadeSpeed * Time.deltaTime;
}
}
}
Color previousGUIColor = GUI.color;
GUI.color = textColour;
GUI.SetNextControlName("");
GUILayout.BeginArea(this.GuiRect,GUI.skin.box);
scrollPos = GUILayout.BeginScrollView(scrollPos);
GUILayout.FlexibleSpace();
for (int i = messages.Count - 1; i >= 0; i--)
{
GUILayout.Label(messages*, labelStyle);*
}
GUILayout.EndScrollView();
GUILayout.BeginHorizontal();
GUI.SetNextControlName(“ConsoleInput”);
Debug.Log ("EventType: “+Event.current.type.ToString()+”, Key: "+Event.current.keyCode.ToString());
Debug.Log ("Before: "+inputLine);
inputLine = GUILayout.TextField(inputLine);
Debug.Log("After: "+inputLine);
GUILayout.EndHorizontal();
GUILayout.EndArea();
GUI.color = previousGUIColor;
//Alternatively, putting this line back in also solves the problem
//inputLine=Regex.Replace(inputLine, “`”, “”); //Ick
}
}
Update: More strange behaviour. With copious debug I’ve noticed that the GUILayout.TextField call adds the backtick to the string when Event.current is a KeyDown event with a keycode of KeyCode.None. That has me scratching my head, it doesn’t seem to make much sense as an event. However, if I Use() that event and return, the backtick doesn’t appear in inputLine at any point.
So that’s another odd-looking solution I could go with. Does anybody know why Unity is producing KeyDown events with no key?