How to read keys that user presses without specifying the exact key? - c#

Basically what I need is an idea how to shorten my code.
So what I have now is an IF series to get the keys that user presses:
if (Input.GetKeyDown(KeyCode.I))
{
AddToBuffer("I");
}
else if (Input.GetKeyDown(KeyCode.N))
{
AddToBuffer("N");
}
else if (Input.GetKeyDown(KeyCode.F))
{
AddToBuffer("F");
}
It works perfectly well, but what I want is to shorten it so it would be possible to save to buffer any key (better, as a string)
So that I would no more have to specify what key was pressed.
(Maybe something like TryParse etc.)

InputString contains a string all keys pressed down on the current frame. It is recommended to break the string down into characters as shown in the input string example in Unity documentation, as inputString can contain backspace '\b' and enter '\n' characters.
An example of listening for cheatcodes might look like this:
string cheatCode = "money";
int cheatIndex = 0;
void Update()
{
if(Input.anyKeyDown)
{
foreach (char c in Input.inputString)
{
if(c == cheatCode[cheatIndex])
{
//the next character was entered correctly
Debug.Log("The next character {0} was entered correctly", c);
//On the next key down, check the next character
cheatIndex++;
} else
{
//The character was not correctly entered, reset the cheat index back to the start of the code
Debug.Log("Cheat code invalid. {0} was not the next character", c);
cheatIndex = 0;
}
}
if(cheatIndex == cheatCode.Length)
{
Debug.Log("Cheat code was successfully entered")
}
}
}
I have not written this in Unity and tested it, so your mileage may vary.

You can use "any key": https://docs.unity3d.com/ScriptReference/Input-anyKey.html
if (Input.anyKey)
{
Debug.Log("A key or mouse click has been detected");
// get the pressed key:
String keycode = Event.current.keyCode.ToString();
}

Related

How to clear the first key press immediately after the short dialog box,if it is a wrong entry in a text box

I'm checking the user ID in the text box. And it can not start with a letter or digit '0'. I can catch the wrong entry and send a message to the screen. But the wrong entry will be in the text box until I hit another key. And if this is an acceptable digit then the wrong entry stays at the beginning of the string. So I need to get rid of the wrong entry immediately after the message dialog box. Any suggestion?
private void TxtUserID_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar))
{
MessageBox.Show(" Your User ID can not begin with a letter !!!");
//txtUserID.Text = string.Empty;
txtUserID.Clear();
}
else if (e.KeyChar == '0')
{
MessageBox.Show("Your User ID can not begin with 0 !!!");
txtUserID.Text = string.Empty;
}
}// end of keypress
I suggest using TextChanged instead of KeyPress event: whatever changed TxtUserID.Text (e.g. Paste, or, imagine, user put "12340" and then deleted "1234" in order to obtain "0") validate the TxtUserID
private static bool IsNameValid(string name) {
if (string.IsNullOrEmpty(name))
return true;
else if (name.Any(c => c < '0' || c > '9')) {
MessageBox.Show("Your User ID must contain digits only!");
return false;
}
else if (name.StartsWith("0")) {
MessageBox.Show("Your User ID must not start from 0!");
return false;
}
return true;
}
private void TxtUserID_TextChanged(object sender, EventArgs e) {
if (!IsNameValid(TxtUserID.Text))
txtUserID.Clear(); // Taken from the question
}
Edit: As Thomas Voß pointed out, clearing the entire text can be to cruel for a user (imagine that he's printed "1001234566978563" and then decided to remove leading "100"), probably
txtUserID.Text = string.Concat(txtUserID
.Text
.Where(c => c >= '0' && c <= '9') // Digits only
.SkipWhile(c => c == '0')); // Trim all starting '0'
instead of txtUserID.Clear(); when we remove all characters but digits and trim leadibng 0 is a better choice.

detect key press

I have a code where I do something when a Key is pressed
if (Console.ReadKey(true).Key == ConsoleKey.G)
{
Logger.Trace("Opening the GUI...");
}
How to detect if key is pressed by using character as A-B? I store shortcut letter in file and want to know if pressed but need to detect it by string and not ConsoleKey.
You can use char.IsLetter() to check if its an alphabet
ConsoleKeyInfo keyinfo;
Console.ReadKey();
while (!(Console.KeyAvailable ))
{
keyinfo = Console.ReadKey();
if (char.IsLetter(Console.ReadKey().KeyChar))
{
}
}
Save the Console.ReadKey result into a string variable and append further keystrokes and check with
if(inputString.Contains(key)){
doSomething()
}
Have a look at the following answers:
https://stackoverflow.com/a/16037492/4992212
Detect when two keys are pressed at the same time

How do I make one word in a text box end a program?

So one of the forms I have to create is where you enter a first and last name and then it splits the two names and puts them next to the appropriate labels, form design: https://gyazo.com/9b34dca0c1cd464fd865830390fcb743 but when the word stop is entered in any way e.g. Stop, StOp, sToP etc. it needs to end.
private void btnSeparate_Click(object sender, EventArgs e)
{
string strfullname, strgivenname, strfamilyname, strfirstname;
int int_space_location_one, int_space_location_two;
strfullname = txtFullName.Text;
int_space_location_one = strfullname.IndexOf(" ");
strgivenname = strfullname.Substring(0, int_space_location_one);
lblGivenEntered.Text = strgivenname;
strfirstname = strfullname.Remove(0, int_space_location_one + 1);
int_space_location_two = strfirstname.IndexOf(" ");
strfamilyname = strfirstname.Substring(int_space_location_two + 1);
lblFamilyEntered.Text = strfamilyname;
}
This is my current code, I have tried many different ways to get the word stop to end it but it wont work so that's why there is currently no code trying to stop the program, the main problem I get is because it is searching for a space between the first and last name and it obviously doesn't have one for one word it just crashes.
Any help with this would be amazing, thanks in advance.
Just hook up the TextChanged event and go like this:
private void TextChanged(Object sender, EventArgs e)
{
// If text, converted to lower-characters contains "stop" -> Exit
if(txtFullName.Text.ToLower().Contains("stop"))
{
// What I understand as "stopping it".
Application.Exit();
}
}
IF with "stop it" you mean to cancle the operation:
private void btnSeparate_Click(object sender, EventArgs e)
{
// If text, converted to lower-characters contains "stop" -> Exit
if (txtFullName.Text.ToLower().Contains("stop"))
{
// What I understand as "stopping it".
Application.Exit();
}
else
{
// Your code inside the else block
}
}
Short version of everything: Also covering no spaces problem
private void btnSeparate_Click(object sender, EventArgs e)
{
// Save how many words are inside
int wordsInText = txtFullName.Text.Split(' ').Length;
// Save if "stop" was typed into the textbox
bool stopExisting = !txtFullName.Text.ToLower().Contains("stop");
// If text has exactly 3 words and "stop" is NOT existing
if (wordsInText == 3 && !stopExisting)
{
// Save array of splitted parts
string[] nameParts = txtFullName.Text.Split(' ');
// This is never used??
string strfirstname = nameParts[1];
// Set name-parts to labels
lblGivenEntered.Text = nameParts[0];
lblFamilyEntered.Text = nameParts[2];
}
// If text has NOT exactly 3 words and "stop" is NOT existing
else if(wordsInText != 3 && !stopExisting)
{
// If there are no 3 words, handle it here - MessageBox?
}
// If "stop" IS existing
else if(stopExisting)
{
// If text contains "stop" handle it here
// Application.Exit(); <-- if you really want to exit
}
}
You could just check, if one of the entered words is equal to the word "stop". There you need a StringComparions which ignores the case. Or you could parse the entered word into lower/upper-cases.
So if the check is true, you could just end the program with
Environment.Exit(0);
You could just check, if one of the entered words is equal to the word "stop". There you need a StringComparions which ignores the case. Or you could parse the entered word into lower/upper-cases.
So if the check is true, you could just end the program with
Environment.Exit(0);
Code:
if (strfullname.ToLowerInvariant().Contains("stop"))
{
Environment.Exit(0);
}

Unity Input Field Lock previously typed characters after a time

I've been messing around with a word game in Unity C# and have come to a standstill regarding an anti-cheat mechanic I want to implement.
Once the first letter has been entered into the input field, I start running a 2 second timer. After the 2 seconds, in the player does not submit or type another letter, the input field should lock the previously typed letters in place on the input field and any letters typed after should be typed after it.
Here's the code I have so far:
currTime = 0;
hasInput = false;
lockedString = "";
void Update(){
if(hasInput){
currTime += Time.deltaTime * 1;
if(currTime >= 2){
//Stores current string value of input field
lockedString = inputField.text;
}
}
}
void OnInputValueChange(){
currTime = 0;
hasInput = true;
if(lockedString != ""){
inputField.text = lockedString + inputField.text;
}
}
Right now I'm running OnInputValueChange() whenever the input field's value is changed. I also manage to store the string that's been entered so far once the timer hits 2 seconds, but I do not know how to make it so that the input field "locks" the locked string into the front and allow changes to the letters typed behind it. The code inputField.text = lockedString + inputField.text; simply adds the lockedString variable to the input field every time the value gets changed.
The desired outcome is as such in pseudo-code:
//User types "bu"
//2 second timer starts
//During these 2 seconds, user can delete "bu" or continue typing
//User deletes "bu" and types "ah"
//Once the 2 second timer ends, whatever string is now in input is locked
//"ah" is now locked at the front of the input field
//After locking "ah", user cannot delete it anymore, but can continue typing
Any insight to how I might achieve something like this will be most helpful. Thanks for taking the time to help, I really appreciate it!
Currently, you are simply concatenating the string. You will want to check if the string starts with the same characters, and if not, completely overwrite the input:
void Update() {
if (hasInput && ((Time.time - inputTime) > 2f))
{
//Stores current string value of input field
lockedString = inputField.text;
hasInput = false;
}
}
void OnInputValueChange() {
inputTime = Time.time;
hasInput = true;
if ((lockedString.Length > 0) && (inputField.text.IndexOf(lockedString) != 0)) {
// Replace invalid string
inputField.text = lockedString;
// Update cursor position
inputField.MoveTextEnd(false);
}
}
Note: I have implemented an alternate method of measuring the time passed. Feel free to replace this with your own method.

Keyboard input doubles each keystroke

I've been working on making a dozenal calculator, so far it's going well. I have a UI that allows me to click numerals in, but something strange happens when I use my numpad to input my numbers.
When I press any number on my numpad instead of clicking, I get doubles.
example:
If I click 2 on screen, I get "2"
If I press 2 on my numpad, I get "22"
Here's part of my UI code:
if(GUI.Button(new Rect(113, 186, 47, 30), numeral[2]))
AppendNumber(numeral[2]);
Here's part of my keyboard code:
if(Input.GetKeyDown("[2]"))
AppendNumber(numeral[2]);
Here's my append code:
void AppendNumber (string num)
{
if (opIsActive == false)
{
slotA = num;
} else {
slotB = num;
}
if (currentNumber != numeral[0])
{
currentNumber = currentNumber + num;
if (opIsActive == false)
{
slotA = currentNumber;
} else {
slotB = currentNumber;
}
} else {
currentNumber = num;
}
}
Any ways, for now my keyboard function is disabled. If anyone knows what the problem may be, I'd love to see.
Use GetAxis instead of GetKeyDown as pointed out by TaW. For some reason GetKeyDown provided double characters, eg. "22" instead of "2".

Categories

Resources