Hello everyone,
i am relatively new to unity so i think this might be a pretty basic question.
i have a value between 0 and 50. it is defined as an int. i want to manipulate that value by pressing two digits on the numpad in sequence, so for example if i click on 3 and then on 5, the value should be 35 or if i click 0 and 8 the value should be 8. i have no clue how to handle these sequences and form an int out of the two keys.
I am happy about any kind of help. Thanks in advance
It’s not great due to the way unity handles key events. I am not sure if its better with the new input library but try this.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class Tester : MonoBehaviour
{
private const int NUMBER_LENGTH = 2;
private List<int> _numbers = new List<int>();
private void Update()
{
if(TryGetNumericInput(out int number))
{
// Use number here
Debug.Log("HERE: " + number);
}
}
private bool TryGetNumericInput(out int output)
{
if(Input.GetKeyDown(KeyCode.Keypad0) || Input.GetKeyDown(KeyCode.Alpha0)) _numbers.Add(0);
else if(Input.GetKeyDown(KeyCode.Keypad1) || Input.GetKeyDown(KeyCode.Alpha1)) _numbers.Add(1);
else if(Input.GetKeyDown(KeyCode.Keypad2) || Input.GetKeyDown(KeyCode.Alpha2)) _numbers.Add(2);
else if(Input.GetKeyDown(KeyCode.Keypad3) || Input.GetKeyDown(KeyCode.Alpha3)) _numbers.Add(3);
else if(Input.GetKeyDown(KeyCode.Keypad4) || Input.GetKeyDown(KeyCode.Alpha4)) _numbers.Add(4);
else if(Input.GetKeyDown(KeyCode.Keypad5) || Input.GetKeyDown(KeyCode.Alpha5)) _numbers.Add(5);
else if(Input.GetKeyDown(KeyCode.Keypad6) || Input.GetKeyDown(KeyCode.Alpha6)) _numbers.Add(6);
else if(Input.GetKeyDown(KeyCode.Keypad7) || Input.GetKeyDown(KeyCode.Alpha7)) _numbers.Add(7);
else if(Input.GetKeyDown(KeyCode.Keypad8) || Input.GetKeyDown(KeyCode.Alpha8)) _numbers.Add(8);
else if(Input.GetKeyDown(KeyCode.Keypad9) || Input.GetKeyDown(KeyCode.Alpha9)) _numbers.Add(9);
if(_numbers.Count() >= NUMBER_LENGTH)
{
output = ConcatinateNumbers();
_numbers.Clear();
return true;
}
output = default(int);
return false;
}
private int ConcatinateNumbers()
{
int total = 0;
foreach (var number in _numbers)
{
total = (total * 10) + number;
}
return total;
}
}
Here’s a shorter and a bit simpler solution:
int total = 0;
void OnGUI()
{
Event e = Event.current;
if (e.type == EventType.KeyDown && e.character >= '0' && e.character <= '9')
{
int val = (int)(e.character - '0');
total = total *10 + val;
if (total > 99)
total = total % 100;
}
}
Note that I did not test this code in Unity as I don’t have a Unity editor at hand ^^. However I quickly checked the char / int conversion in the .NET fiddle and it works fine.
Be warned in this case the user can enter numbers in an infinite stream up to a value of 99. If the value is larger then only the last input value will stay. Examples:
input Value
--------------
0
4 4
2 42
7 27
3 73
5 35
0 50
8 8
4 84
Since it’s not clear how you want to handle two digit values that are larger than 50 I did not implement any special behaviour. If you really only want the value to change after exactly 2 digits has been entered, you need some additional state like a boolean.
int total = 0;
bool secondDigit = false;
void OnGUI()
{
Event e = Event.current;
if (e.type == EventType.KeyDown && e.character >= '0' && e.character <= '9')
{
int val = (int)(e.character - '0');
total = total *10 + val;
if (secondDigit)
{
// use the value here.
Debug.Log("value: " + total);
total = 0;
}
secondDigit = !secondDigit;
}
}
This would only get a new number (inside the inner if statement) every two button presses. You still need to handle your desired range.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
public int total;
KeyCode[] keyCode = new KeyCode[20];
// Digits will contain each digit for the total. At the bottom there will be digit from the first keypress, and at the top there will be digit from the second keypress. It will be important while constructing the total.
Stack<int> digits = new Stack<int>();
void Awake()
{
// Create the array of 20 elements of type KeyCode. Each element will map to the specified numeric key. For example keycode for "0" will be at positions "0" and "10", "1" at "1" and "11", and so on.
for(int i = 0; i < 10; i++)
{
keyCode *= (KeyCode)((int)KeyCode.Alpha0 + i);*
-
keyCode[i+10] = (KeyCode)((int)KeyCode.Keypad0 + i);*
-
}*
-
}*
-
void Update()*
-
{*
-
if (GetTotal())*
-
Debug.Log(total);*
-
}*
-
public bool GetTotal()*
-
{*
-
for(int i = 0; i < keyCode.Length; i++)*
-
{*
_ if (Input.GetKeyDown(keyCode*))_
_ {_
_ // The modulo here is because the keyCode array contains for example “0” at two positions (at 0 and at 10), and so on._
_ int digit = i%10;*_
* // The first digit must be less than the upper boundary. Do the check.*
* if (digits.Count==0 && digit > 5)*
* return false;*
* // If the first digit is equal to 5, the second digit can only be zero.*
* if (digits.Count==1 && digits.Peek()==5 && digit > 0)*
* return false;*
* // Push the digit on the stack*
* digits.Push(digit);*
* // Then check if the stack has two digits. If so, just remove them from the stack and construct the total number. Remember that when removing digits from the stack the order matters.*
* if (digits.Count == 2)*
* {*
_ total = digits.Pop() + digits.Pop() * 10;_
* return true;*
* }*
* }*
* }*
* return false;*
* }*
}