Search Unity

Question How to .ToString an inputted KeyCode?

Discussion in 'Scripting' started by karsten-heim, Nov 24, 2022.

  1. karsten-heim

    karsten-heim

    Joined:
    May 16, 2022
    Posts:
    63
    I have a hotbar within my game, and I would like the slot number to be saved as a variable based on what key is pressed, and since doing:
    Code (CSharp):
    1. if(Input.GetKeyDown(KeyCode.1)
    2. {
    3.    // do something
    4. }
    is a bit tedious and inefficient, I would like to store any pressed key as a string, then convert that string to a float if it is an integer, so if there is also a way to only store numbers as a string, that would be helpful knowledge as well, But ideally, this is around I am looking for:

    Code (CSharp):
    1. public string keycode_num;
    2. public int Slotnum;
    3.  
    4. keycode_num = (Input.GetKeyDown(Numeric Keycode pressed)).ToString;
    5. Slotnum = keycode_num;

    but any other not too extensive solutions are appreciated, and only numeric inputs for keycodes may not be necessary because i think that I can just use int.TryParse
     
  2. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,096
    KeyCode is an Enum. Each entry in KeyCode collection already has a corresponding integer assigned to it.
    You just do
    Code (csharp):
    1. var value = (int)myKeyCode;
    But here's a better example for what you're trying to do
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class KeyTrap : MonoBehaviour {
    4.  
    5.   static KeyTrap _instance;
    6.   static public KeyTrap Instance => _instance;
    7.  
    8.   KeyCode? _result;
    9.   public KeyCode? Key => _result;
    10.  
    11.   void Awake() {
    12.     _instance = this;
    13.     Reset();
    14.   }
    15.  
    16.   void Update() {
    17.     if(Input.anyKeyDown) {
    18.       foreach(var item in Enum.GetValues(typeof(KeyCode)) {
    19.         var key = (KeyCode)item;
    20.         if(Input.GetKeyDown(key)) {
    21.           _result = key;
    22.           break;
    23.         }
    24.       }
    25.       enabled = false;
    26.     }
    27.   }
    28.  
    29.   public void Reset() {
    30.     _result = null;
    31.     enabled = false;
    32.   }
    33.  
    34. }
    You can now use this elsewhere
    Code (csharp):
    1. // do this when you want to trap a key
    2. myKeyTrap = KeyTrap.Instance; // myKeyTrap is of type KeyTrap
    3. myKeyTrap.enabled = true;
    4. trapActivated = true; // your own state variable
    5.  
    6. // then in some Update
    7. if(trapActivated && myKeyTrap.Key.HasValue) {
    8.   mySlot = myKeyTrap.Key.Value; // mySlot is of type KeyCode
    9.   myKeyTrap.Reset();
    10.   trapActivated = false;
    11. }
    Btw since you're so stressed out with inefficiency you should know that converting anything to string and back to number is among the worst things a programmer can do, especially ones striving for efficiency.
     
    Last edited: Nov 24, 2022
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
  4. karsten-heim

    karsten-heim

    Joined:
    May 16, 2022
    Posts:
    63
    Yes, I have that in my code, but it gives me the error that the string is not in a proper format, which I cannot find a solution for, and Input.inputString sometimes works, but mostly just floods my console with errors despite me not pressing anything.

    I am mostly looking for something short and sweet, and am trying to find a viable combination of Input.inputString and int.TryParse or something
     
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,819
    Do you actually need to save it as a number though?

    Just save the string, then check if the input string matches the string you saved.

    Not particularly elegant but it should work.

    If you need the number for display purposes, Debug.Log() the string you get, and just write a way to neaten up the string (only for display purposes, not for the purpose of parsing it as an int).
     
  6. karsten-heim

    karsten-heim

    Joined:
    May 16, 2022
    Posts:
    63
    the issue is Input.inputString does not really give me any actual most of the time, it just floods my console with the time (like 09:42:25) whenever I try to Debug.Log it, rather than the keyboard input promised on unity documentation, so the input from the keys appears to be negated by the time being Debug.Logged 10+ times a second
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    Which if you read the documentation link I provided above, is EXACTLY what they promise.

    Description: Returns the keyboard input entered this frame.

    Test it and do nothing when nothing was inputted this frame.
     
  8. karsten-heim

    karsten-heim

    Joined:
    May 16, 2022
    Posts:
    63
    I read the doc link you put kurt, but apparently fixed update was screwing up my input, so this worked in the end
    Code (CSharp):
    1. void Update()
    2.     {
    3.         slotkey = Input.inputString;
    4.         bool l = int.TryParse(slotkey, out slotnum);
    5.         if (l == true)
    6.         {
    7.             Debug.Log(slotnum);
    8.         }
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    Any method anywhere that references the word "frames" has a very specific lifecycle meaning in Unity3D.

    FixedUpdate() has nothing to do with frames.

    FixedUpdate() should ONLY be used for physics, nothing else.

    Here is some timing diagram help:

    https://docs.unity3d.com/Manual/ExecutionOrder.html

    Two good discussions on Update() vs FixedUpdate() timing:

    https://jacksondunstan.com/articles/4824

    https://johnaustin.io/articles/2019/fix-your-unity-timestep