Search code examples
c#arraysunity-game-enginegame-developmentdecrement

Decrementing last string element in array without removing it in C#?


I'm currently doing a demo on Unity where I've put the whole alphabet in an array. For the backspace function I want to decremt the last string element in the array, but it doesnt work.

[SerializeField] private GameObject keyboard;

[SerializeField] private Text keyboardInput;

private KeyCode[] MyKeys = {KeyCode.A, KeyCode.B,KeyCode.C,KeyCode.D, KeyCode.E,KeyCode.F,KeyCode.G,KeyCode.H,KeyCode.I,KeyCode.J,KeyCode.K,KeyCode.L,KeyCode.M,KeyCode.N,KeyCode.O,KeyCode.P,KeyCode.Q,KeyCode.R,KeyCode.S,KeyCode.T, KeyCode.U ,KeyCode.V,KeyCode.W,KeyCode.X,KeyCode.Y,KeyCode.Z, KeyCode.Space, KeyCode.Backspace };

private string[] currText;
void Start()
{
    keyboardInput.text = currText.ToString();
}

private void typeKeys()
{

    for (var i = 0; i < MyKeys.Length; i++)
    {

        if (Input.GetKeyDown(MyKeys[i]))
        {

            if (i == 0)
            {
                keyboardInput.text += "a";
            }
            else if (i == 1)
            {
                keyboardInput.text += "b";
            }
            else if (i == 2)
            {
                keyboardInput.text += "c";
            }
            else if (i == 3)
            {
                keyboardInput.text += "d";
            }
            else if (i == 4)
            {
                keyboardInput.text += "e";
            }
            else if (i == 5)
            {
                keyboardInput.text += "f";
            }
            else if (i == 6)
            {
                keyboardInput.text += "g";
            }
            else if (i == 7)
            {
                keyboardInput.text += "h";
            }
            else if (i == 8)
            {
                keyboardInput.text += "i";
            }
            else if (i == 9)
            {
                keyboardInput.text += "j";
            }
            else if (i == 10)
            {
                keyboardInput.text += "k";
            }
            else if (i == 11)
            {
                keyboardInput.text += "l";
            }
            else if (i == 12)
            {
                keyboardInput.text += "m";
            }
            else if (i == 13)
            {
                keyboardInput.text += "n";
            }
            else if (i == 14)
            {
                keyboardInput.text += "o";
            }
            else if (i == 15)
            {
                keyboardInput.text += "p";
            }
            else if (i == 16)
            {
                keyboardInput.text += "q";
            }
            else if (i == 17)
            {
                keyboardInput.text += "r";
            }
            else if (i == 18)
            {
                keyboardInput.text += "s";
            }
            else if (i == 19)
            {
                keyboardInput.text += "t";
            }
            else if (i == 20)
            {
                keyboardInput.text += "u";
            }
            else if (i == 21)
            {
                keyboardInput.text += "v";
            }
            else if (i == 22)
            {
                keyboardInput.text += "w";
            }
            else if (i == 23)
            {
                keyboardInput.text += "x";
            }
            else if (i == 24)
            {
                keyboardInput.text += "y";
            }
            else if (i == 25)
            {
                keyboardInput.text += "z";
            }
            else if (i == 26)
            {
                keyboardInput.text += " ";
            }
            else if (i == 27)
            {
                currText = currText.Take(currText.Length - 1).ToArray();
            }
        }
    };
}

// Update is called once per frame
void Update()
{

    typeKeys();
}

This is the part im trying to get to work

                else if (i == 27)
            {
                currText = currText.Take(currText.Length - 1).ToArray();
            }

See video for clarification

What I mean by that it doesnt work is that I cant remove the last letter from my array thus giving the effect of using backspace in a sentence in my virtual setup. This is the whole script.


Solution

  • Let's start by reducing the amount of code. And then, after that, we can also take advantage of two facts; Unity has a KeyCode enum, and the alphabet is ordered in values from 'a' through to 'a'+25. I'll clarify that with a bit of code:

    private Text keyboardInput;
    List<char> charList = new List<char> ( );
    
    private void typeKeys( )
    {
        var length = charList.Count;
    
        if ( Input.GetKeyDown ( KeyCode.Space ) )
            charList.Add ( ' ' );
    
        if ( Input.GetKeyDown ( KeyCode.Backspace ) && length  > 0 )
            charList.RemoveAt ( length - 1 );
    
        for ( var i = 0; i < 26; i++ )
            if ( Input.GetKeyDown ( KeyCode.A + i ) ) charList.Add ( ( char ) ( 'a' + i ) );
    
        if ( length != charList.Count ) keyboardInput.text =  string.Concat ( charList );
    }
    

    What I'm doing here, is first checking for the Space key, followed by the Backspace key. After that, I iterate through the alphabet characters, adding the i value to the KeyCode.A. Remember that enums are just int by default. If that's a match, we add the corresponding i value to the 'a' character and add that to the List<char> list, remembering to also cast the resulting value back to a char first.

    Finally, if the length of your character array has changed, then, and only then, do we update your keyboardInput.text. That's to help save string garbage being produced every single frame. We can Concat a char IEnumerable to a string.

    Using this method you can remove the whole line that starts with private KeyCode[] MyKeys. You don't need to store all of the KeyCode values in an array to check against.