Apply keycode values to variables

Hello guys, i am creating a platformer game where the player can change his character from an running one, to an swimming one and so on in order to complete levels

I already have this few lines to change the state, however, it is only possible to switch between the given patterns (up or down a state) you see my current script follown:

public KeyCode NextState;
public KeyCode PreviousState;

public PlayerState playerState;
public int playerStateIndex;

void PlayerStateHandler()
    {   
        switch (playerState)
        {   // Player State Properties

            case PlayerState.normal:
                // Set Attributes
                break;
            case PlayerState.run:
                // Set Attributes
                break;
            case PlayerState.rope:
                // Set Attributes
                break;
            case PlayerState.swim:
                // Set Attributes
                break;

        }
    }
    void ChangePlayer()
    {
        if (Input.GetKeyDown(NextState))
            playerStateIndex++;
        if (Input.GetKeyDown(PreviousState))
            playerStateIndex--;

        // Get Player State based on Input
        if (playerStateIndex == 4 || playerStateIndex == -1)
            playerStateIndex = 0;

        switch (playerStateIndex)
        {   // Declare States to their Index
            case 0:
                playerState = PlayerState.normal;
                break;
            case 1:
                playerState = PlayerState.run;
                break;
            case 2:
                playerState = PlayerState.rope;
                break;
            case 3:
                playerState = PlayerState.swim;
                break;
        }
    }

as I build up the game now, i planned to manage it with an array of KeyCode, see the example below:

public KeyCode[] stateButtons;
public string changeIndex;

void Start()
    {
        stateButtons = new KeyCode[] {KeyCode.Alpha1, KeyCode.Alpha2, KeyCode.Alpha3, KeyCode.Alpha4};
    }

void Update()
{
     foreach (KeyCode stateIndex in stateButtons)
        {
            if (Input.GetKeyDown(stateIndex))
            {
                changeIndex = stateIndex.ToString();
                int.TryParse(changeIndex, out playerStateIndex);
                Debug.Log(playerStateIndex);
            }
        }
}

now, my problem is that playerStateIndex is not the value that I hit on my Keyboard. (I hit 1-4)
somehow I can not figure out how to handle that in an other way. i guess there is certenly a more elegant way than convert from string to int. I also thought about to declare every button, makes this more sense? I am no professional as you can see :face_with_hand_over_mouth:

any form of help is desirable and greatly appreciated!
thanks in advance :blush::blush:

One flexible solution would be to use a dictionary to map keys to states. Any number of key/states can be trivially mapped this way. You can also wrap the foreach loop with an Input.anyKeyDown check to ensure the code only runs when a key is down:

    private Dictionary<KeyCode, PlayerState> keyStateMap = new()
	{
		{ KeyCode.Alpha1, PlayerState.normal },
		{ KeyCode.Alpha2, PlayerState.run },
		{ KeyCode.Alpha3, PlayerState.rope },
		{ KeyCode.Alpha4, PlayerState.swim },
		{ KeyCode.Keypad1, PlayerState.normal },
		{ KeyCode.Keypad2, PlayerState.run },
		{ KeyCode.Keypad3, PlayerState.rope },
		{ KeyCode.Keypad4, PlayerState.swim }
	};

	private void Update ()
	{
		if (Input.anyKeyDown)
		{
			foreach (var key in keyStateMap.Keys)
			{
				if (Input.GetKeyDown(key) && keyStateMap.TryGetValue(key, out playerState))
				{
					PlayerStateHandler();
					break;
				}
			}
		}
	}

And, if PlayerState is an enum then the underlying type is an integer, so you can remove playerStateIndex and operate on playerState directly, simplifying the ChangePlayer method:

public enum PlayerState
{
    normal = 0,
    run    = 1,
    rope   = 2,
    swim   = 3
}

public PlayerState playerState;

void ChangePlayer()
{
    if (Input.GetKeyDown(NextState))
        playerState++;
    if (Input.GetKeyDown(PreviousState))
        playerState--;

    // Get Player State based on Input
    if (playerState > PlayerState.swim || playerState < PlayerState.normal)
        playerState = normal;
}

Lastly, what you’re doing here is state management. A tried and tested design pattern for this is called an Finite State Machine or FMS, which I highly recommend.