Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

GUI.TextField submission via "return" key...

Discussion in 'Immediate Mode GUI (IMGUI)' started by CapnJ, Dec 2, 2010.

  1. CapnJ

    CapnJ

    Joined:
    Aug 6, 2009
    Posts:
    29
    Ahoy, I'm having all sorts of trouble trying to get the "enter" key to be recognized while a textField has focus. What i'd like to do is have the user type in his name and then hit the "enter" key directly (vs using the mouse) to call a submit function. Below is where my code is at the moment:

    Code (csharp):
    1. function OnGUI(){
    2.    
    3.     GUI.skin = mySkin;
    4.    
    5.     GUI.SetNextControlName ("MyTextField");
    6.     GUI.FocusControl ("MyTextField");    
    7.    
    8.     stringToEdit = GUI.TextField (Rect (Screen.width/ 2 - 100, Screen.height / 2 - 135, 200, 40), stringToEdit, 25);
    9.     if (GUI.changed == true){
    10.         print("GUI CHANGED");
    11.         if (Input.GetKeyDown(KeyCode.Return)){
    12.             print("SubmissionHit");
    13.     }
    14.     }
    15.     if (GUI.Button (Rect (Screen.width/ 2 - 100, Screen.height / 2 - 80, 200, 40), "Submit")) {
    16.         SubmitName();
    17.     }
    18.     if (Input.GetKeyUp(KeyCode.Escape)){
    19.             Application.Quit();
    20.     }
    21.    
    22. }
    Using the button on stage works just fine via mouse, but this application is mainly a keyboard input app. Any thoughts?:confused:
     
  2. laurie

    laurie

    Joined:
    Aug 31, 2009
    Posts:
    638
    What's the problem you're having? Is that code not doing anything when Enter or Return are pressed? If so, the problem may be that the return key-press event has already been consumed by the TextField component; you may need to move the test before the control rendering. You may also need to use Event.current.isKey and Event.current.keyCode rather than using the Input class. Or I may be making suggestions related to a different problem that what you're having... ?
     
    tigerleapgorge likes this.
  3. CapnJ

    CapnJ

    Joined:
    Aug 6, 2009
    Posts:
    29
    You got it, the Return button does nothing at all. I'm interested in the Event code, The return key has no problem being caught by this:
    Code (csharp):
    1. var e : Event = Event.current;
    2.     if (e.isKey) {
    3.         Debug.Log("Detected key code: " + e.keyCode);
    4.     }
    So i'm guessing your code
    should work fine. But, how would one go about using it? Like this?:

    Code (csharp):
    1. if (Event.current.keyCode == "Return"){
    2.         print("yay");
    3.     }
    Returns an error at the moment.
     
    tigerleapgorge likes this.
  4. appels

    appels

    Joined:
    Jun 25, 2010
    Posts:
    2,687
    Code (csharp):
    1. (Event.current.type == EventType.keyDown  Event.current.character == '\n')
     
    tigerleapgorge likes this.
  5. laurie

    laurie

    Joined:
    Aug 31, 2009
    Posts:
    638
    Not sure that ".character == '\n'" is necessarily portable. .keyCode should be more reliable, but Event.keyCode is of type KeyCode, not of type String. Try
    Code (csharp):
    1. if (Event.current.isKey  Event.current.keyCode == KeyCode.Return) { ... }
     
    bullze and tigerleapgorge like this.
  6. Charles-Van-Norman

    Charles-Van-Norman

    Joined:
    Aug 10, 2010
    Posts:
    86
    Why are the simplest things in Unity so hard? No one seems to have posted anything that answers the original question, so I figured it out. Here is the working C# code to accept a Return key press to make the text field go away:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class example : MonoBehaviour
    6. {
    7.  
    8. bool userHasHitReturn = false;
    9. string stringToEdit = "";
    10.  
    11.  void OnGUI() {
    12.         Event e = Event.current;
    13.         if (e.keyCode == KeyCode.Return) userHasHitReturn = true;
    14.         else if (false == userHasHitReturn)     stringToEdit = GUI.TextField(new Rect(0,0,100,50), stringToEdit, 25);
    15.     }
    16. }
    17.  
     
    Last edited: Feb 10, 2011
  7. Vimalakirti

    Vimalakirti

    Joined:
    Oct 12, 2009
    Posts:
    755
    ccvannorman,

    oh.. it's C. C. VanNorman. Got it.

    Hey CC,
    Thanks for posting your solution. That definitely helped me get my focus to focus on return like I wanted it to. Cool.
     
  8. QuietPixel

    QuietPixel

    Joined:
    Jul 29, 2010
    Posts:
    51
    I am seeing the same problem. Input.GetKey (KeyCode.Return) no longer works on Macs (either in the editor, standalone builds, or webplayers), however, it still works fine on PCs. I have code that was working fine checking Input.GetKey (KeyCode.Return), but now does not work. This is the first time I have tested the code in Unity 3, so I do not know when this bug showed up in U3.

    I also tried Input.GetKey ("return"), Input.GetKey ("enter"), Input.GetKeyUp (KeyCode.Return), and Input.GetKeyDown (KeyCode.Return).

    I tried your solution of getting the current event and checking the keyCode directly and it worked fine.

    Again, this seems to be a bug on Macs only. (I am currently using U3.3.0f4).
     
  9. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    Inside OnGUI, you should check Event.current and not Input.GetKey.

    You can either check

    if (if (Event.current.type == EventType.KeyDown Event.current.character == '\n')

    or

    if (Event.current.type == EventType.KeyDown (Event.current.keyCode == KeyCode.Enter || Event.current.keyCode == KeyCode.Return))

    you need to do this before GUI.TextField, otherwise the textfield will eat your keydown event
     
    GubaLord and andersemil like this.
  10. Cawas

    Cawas

    Joined:
    Jan 14, 2010
    Posts:
    121
    wish this was on answers so I could vote up nicholas post!
     
  11. unimechanic

    unimechanic

    Joined:
    Jan 9, 2013
    Posts:
    155
  12. Giannis7312777

    Giannis7312777

    Joined:
    Sep 4, 2012
    Posts:
    8
    Thank you Nicholas Francis! :D
     
  13. semiessessi

    semiessessi

    Joined:
    Jun 14, 2013
    Posts:
    3
    this solves the individual case, but what about the general case of dealing with input? what if return also does something else in a different context. how can we manage this? ourselves with labouious code? more generally what if we want to bind keys to behaviour in the most general way possible? the simple solution is to allow 'consuming' input in a deterministic way... where if someone handles a keypress they can choose that no-one else can handle it. this makes prioritising all the uses of the keys quite straightforward (you will need another update order for inputs..)

    maybe there is a solution buried in docs or examples somewhere but its neither obvious through e.g. intellisense nor intuitively named (if it even exists).

    > Why are the simplest things in Unity so hard?

    yeah, i was constantly surprised by this for a while too - i have reached the conclusion that its a combination of absent/shoddy documentation, poor class names and general lack of engine development experience on the team. the editor is fantastic, it really is, and having a reasonably finished editor is much more important than the quality of the engine...

    however its more than a little irritating... the example i give of input is a good one. i suspect part of why the current solution is shoddy is the lack of respect for the importance of determinism and ordering in the engine in general which makes it potentially difficult to solve. update orders and having multiple of them for differing contexts (render vs. update is the classic example) and strong deterministic control over it (draw order is a classic example) is extremely valuable... these are realisations from 15+ years ago, nothing new.

    they can argue all they want about the difficulty of cross platform but i have tons of native code across the same platform set that works just fine if you do it right then stuff like this becomes much easier... mono is a crude sledgehammer for this purpose and one that hits you a bit as well.

    unity uses the component model but why hasn't it leveraged it here with an 'inputhandler' component? they could be iterated over in a custom specified order. sadly it does not seem to be the case that unity allows using components for what they were designed for - we instead have a monolithic entity construction kit with all of the disadvantages of both components and monolithic entities. there is FindObjectsOfType.. but the name and its interface scare me off - its a function which indicates that it does something actively instead of retuning the already existing array every component should have internally, it takes a system.type or is a generic which indicates that the implementation is inconsiderate (why not have a generic component base class that provides a correctly typed interface?)

    sadly i can go on for a very long time picking flaws and suggesting tried and tested solutions with many advantages...

    no i don't want a job at unity. sorry. i can forsee the rage quit that would follow already :p
     
  14. Helical

    Helical

    Joined:
    Mar 2, 2014
    Posts:
    50
    you can't appease everyone semiessessi, I have the same problem right now and am looking for a clean solution.
     
  15. proxyjan

    proxyjan

    Joined:
    Mar 29, 2014
    Posts:
    1
    I'm using windows (draggable windows, one in the other and blah blah blah) And...
    This worked for me, Only this one :), Thanks laurie,
     
  16. Freddy888

    Freddy888

    Joined:
    Sep 13, 2014
    Posts:
    165
    Hi,

    I got this working kind of. My code follows. You can see I print to the console. But it's writing to the console 4 times for each single press of the 'return' key.

    Any ideas ?

    Thanks
    Code (CSharp):
    1.     private string textFieldString = "text field";
    2.  
    3.     void OnGUI () {
    4.  
    5.         Event e = Event.current;
    6.         if (e.keyCode == KeyCode.Return) {      
    7.             print (textFieldString);
    8.         }
    9.         textFieldString = GUI.TextField (new Rect (25, 25, 100, 30), textFieldString);
    10.     }
     
  17. Freddy888

    Freddy888

    Joined:
    Sep 13, 2014
    Posts:
    165
    Found the problem, used this line instead :

    Code (CSharp):
    1. if (e.type == EventType.keyDown && e.keyCode == KeyCode.Return)
     
    CodeWard and Stardog like this.
  18. Alex_Gol

    Alex_Gol

    Joined:
    Feb 28, 2015
    Posts:
    1
    When I use
    Code (CSharp):
    1. void Update() {
    2.         if (InputField.isFocused && InputField.text != "" && Input.GetKey (KeyCode.Return)) {
    3.                 /*Message Sending Operations*/
    4.         }
    I have to press return key twice in order to send a message. It's like loosing focus on InputField for the first press and sends on second.
    If I try to use something like

    Code (CSharp):
    1. void Update() {
    2.         if (InputField.isFocused && InputField.text != "" && Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return) {
    3.                 /*Message Sending Operations*/
    4.         }
    With or without Event.current.type == EventType.KeyDown
    It gives this
     
  19. madvas

    madvas

    Joined:
    Jun 14, 2015
    Posts:
    6

    You must put it in onGUI like this
    Code (CSharp):
    1.  
    2. voidOnGUI ()
    3. {
    4. Evente = Event.current;
    5. if (e.type == EventType.keyDown && e.keyCode == KeyCode.Return) {
    6. }
    7. }
     
  20. BilboX

    BilboX

    Joined:
    Oct 11, 2013
    Posts:
    4
    Here is a dedicated class I wrote this morning for text editing. This is for float values but it is easy to modify it to any type you want, or even change it to template one. It displays a value, displays in yellow if it is beeing edited, in red if there is an error, and return a changed flag. The current modification is also cancelable:

    Code (CSharp):
    1. public class FloatInputTextfield
    2. {
    3.     public FloatInputTextfield(float val=0.0f)
    4.     {
    5.         Value = val;
    6.     }
    7.  
    8.     public float Value
    9.     {
    10.         get { return validValue; }
    11.         set
    12.         {
    13.             validValue = currentValue = value;
    14.             text = "" + validValue;
    15.             error = isEdited = false;
    16.         }
    17.     }
    18.  
    19.     static GUIStyle style = null;
    20.  
    21.     float validValue = 0.0f;
    22.     float currentValue = 0.0f;
    23.     bool isEdited = false;
    24.     bool error = false;
    25.     string text = "";
    26.  
    27.     public bool OnGUI(Rect area)
    28.     {
    29.         if (style == null) // Has to be done with OnGUI call
    30.         {
    31.             style = new GUIStyle(GUI.skin.textField);
    32.             style.alignment = TextAnchor.MiddleCenter;
    33.         }
    34.  
    35.         bool changed = false;
    36.         Event e = Event.current;
    37.         if (e.type == EventType.keyDown)
    38.         {
    39.             if (e.keyCode == KeyCode.Return)
    40.             {
    41.                 Value = currentValue;
    42.                 changed = true;
    43.             }
    44.             else
    45.             if (e.keyCode == KeyCode.Escape)
    46.             {
    47.                 Value = validValue;
    48.             }
    49.         }
    50.         Color saved = GUI.color;
    51.         GUI.color = error ? Color.red : (isEdited ? Color.yellow : saved);
    52.         text = GUI.TextField (area, text, style);
    53.         error = !float.TryParse (text, out currentValue);
    54.         GUI.color = saved;
    55.         isEdited = error || validValue != currentValue;
    56.  
    57.         return changed;
    58.     }
    59. }
    Then, you only have to use it this way:

    Code (CSharp):
    1. FloatInputTextfield myFloatValue = new FloatInputTextfield(5.0);
    2. void OnGUI()
    3. {
    4.     float v = 0.0f;
    5.     if(myFloatValue.OnGUI(new Rect(10,10,50,30)))
    6.          v= myFloatValue.Value;
    7. }
     
  21. ginodp2020

    ginodp2020

    Joined:
    Apr 21, 2020
    Posts:
    1
    string input=GUI.TextArea(new Rect(10,10,100,100),input);
    if (input.Contains("\n")){
    Debug.Log("you pressed return");
    }