Search Unity

Way to condense script for connecting controllers for players?

Discussion in 'Scripting' started by Pix77, Aug 16, 2019.

  1. Pix77

    Pix77

    Joined:
    Mar 18, 2018
    Posts:
    21
    I made this simple but pretty inefficient code that allows me to assign a controller number to a player slot, and the slots are temporarily stored in a list, and this snippet of code is repeated four times for each slot with else ifs and the respective numbers changed for each. I'm assuming there's a much cleaner and simpler way to do this, and was wondering if there is a way how, this script works but it's more than likely sloppy and can be done better. I'd appreciate any help or guidance towards cleaning it up, thank you.
    Code (CSharp):
    1. if(slot == 1)
    2.         {
    3.             if (Input.GetKeyDown(KeyCode.Joystick1Button0) && !players.Contains(1))
    4.                 players[0] = 1;
    5.             else if (Input.GetKeyDown(KeyCode.Joystick2Button0) && !players.Contains(2))
    6.                 players[0] = 2;
    7.             else if (Input.GetKeyDown(KeyCode.Joystick3Button0) && !players.Contains(3))
    8.                 players[0] = 3;
    9.             else if (Input.GetKeyDown(KeyCode.Joystick4Button0) && !players.Contains(4))
    10.                 players[0] = 4;
    11.             if(players[0] != -1)
    12.                 slot++;
    13.         }
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    I haven't messed directly with joystick inputs before, but if Unity doesn't already have something like this, I would probably start by setting up a data structure that allows me to refer to the joystick buttons by index rather than by explicit enum value. Something along the lines of:

    Code (CSharp):
    1. public static class KeyRef
    2. {
    3.     public static readonly List<List<KeyCode>> Joystick;
    4.  
    5.     static KeyRef()
    6.     {
    7.         Joystick = new List<List<KeyCode>>();
    8.  
    9.         // Index 0 reserved to mean "any joystick"
    10.         int index = 0;
    11.         Joystick.Add(new List<KeyCode>());
    12.         Joystick[index].Add(KeyCode.JoystickButton0);
    13.         Joystick[index].Add(KeyCode.JoystickButton1);
    14.         Joystick[index].Add(KeyCode.JoystickButton2);
    15.         // etc.
    16.  
    17.         ++index;
    18.         Joystick.Add(new List<KeyCode>());
    19.         Joystick[index].Add(KeyCode.Joystick1Button0);
    20.         Joystick[index].Add(KeyCode.Joystick1Button1);
    21.         Joystick[index].Add(KeyCode.Joystick1Button2);
    22.         // etc.
    23.     }
    24. }
    If you don't mind relying on the numeric values of these enums being consecutive (which is currently true, and unlikely to change, but it theoretically could), then you can shorten that to:

    Code (CSharp):
    1. public static class KeyRef
    2. {
    3.     public static readonly List<List<KeyCode>> Joystick;
    4.  
    5.     static KeyRef()
    6.     {
    7.         Joystick = new List<List<KeyCode>>();
    8.  
    9.         const int joystickCount = 8 + 1;    // 8 joysticks, plus a special entry at 0 for "any joystick"
    10.         const int buttonCount = 20;    // button codes per joystick
    11.         for (int s = 0; s < joystickCount; ++s)
    12.         {
    13.             var stick = new List<KeyCode>();
    14.             Joystick.Add(stick);
    15.             for (int b = 0; b < buttonCount; ++b)
    16.             {
    17.                 stick.Add((KeyCode)(b + s*buttonCount + (int)KeyCode.JoystickButton0));
    18.             }
    19.         }
    20.     }
    21. }
    Once you have that, you can refer to button B on joystick S by writing
    KeyRef.Joystick[S][B]


    That allows you to refactor your controller assignment code to something like:
    Code (CSharp):
    1. for (int stick = 1; stick <= 4; ++stick)
    2. {
    3.     if (Input.GetKeyDown(KeyRef.Joystick[stick][0]) && !players.Contains(stick))
    4.     {
    5.         players[slot-1] = stick;  // Not entirely sure why the controller for slot 1 is stored at index 0, but for consistency with the OP...
    6.         ++slot;
    7.         break;
    8.     }
    9. }
     
    Pix77 likes this.
  3. Pix77

    Pix77

    Joined:
    Mar 18, 2018
    Posts:
    21
    That a much cleaner solution than my sloppy idea, thank you!