- Home /
c# - How to manipulate a int by pressing two digits on the numpad?
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
Answer by sacredgeometry · Dec 31, 2020 at 06:48 PM
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;
}
}
Your $$anonymous$$athf.Pow line is wrong ^^. You just want to multiply the total by 10 each iteration so $$anonymous$$athf.Pow is unnecessary. $$anonymous$$ultiplying by 10 essentially shifts the decimal number to the left one place. Also your usage of FirstOrDefault and Skip is also unnecessary. Just initialize your total to 0 and iterate over all numbers.
You can also use Unity's event handling method OnGUI to read the numbers. That would simplify the code.
How would multiplying the total (... which would be what?) with the base concatenate a series of numbers i.e. [1,2,3] into the value 123?
Also the First or default takes the first item in numbers incase NU$$anonymous$$BER_LENGTH is set to length 1 the skip would then bypass the concatenation step.
Yeah you could just store it in a string. But that I didnt know if that was what he was asking. If he just wants a text input then I would assume he wouldnt be asking the question as its default behaviour in one and all you need to do is click the ui two times to add one to your scene.
Answer by Bunny83 · Jan 01, 2021 at 09:31 AM
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.
Ahh I didnt know unity had more trad event handling useful to know.
Answer by yummy81 · Jan 01, 2021 at 01:27 PM
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[i] = (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[i]))
{
// 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;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Test : $$anonymous$$onoBehaviour
{
public int total;
int number = 1;
KeyCode[] keyCode = new KeyCode[20];
void Awake()
{
for(int i = 0; i < 10; i++)
{
keyCode[i] = (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[i]))
{
int digit = i%10;
int length = (int)$$anonymous$$ath.Log10(number) + 1;
if (length==1 && digit > 5)
return false;
else if (length==2 && number%10==5 && digit > 0)
return false;
if (length==1)
{
number = number * 10 + digit;
}
else if (length==2)
{
total = number%10 * 10 + digit;
number = 1;
return true;
}
}
}
return false;
}
}
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
2D Topdown Shooter Enemy Knockback 0 Answers
Object fitting system (2d array) Tetris style. 1 Answer
Illuminating a 3D object's edges OnMouseOver (script in c#)? 1 Answer