Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

How to detect what controller you're using...

Discussion in 'Scripting' started by astracat111, Apr 3, 2019.

  1. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    685
    Hello there,

    Recently I've been working on detecting what type of controller is plugged in. I've been using InControl which is working splendidly. I want to detect if a Playstation 4 controller is plugged in, as my game will show Playstation 4 controller graphics for a PS4 controller, and for everything else Xbox controller graphics.

    There was a solution that was given to me online that looks like this:

    Code (CSharp):
    1. string[] joystickNames = Input.GetJoystickNames();
    2.  
    3.         foreach (string joystickName in joystickNames)
    4.         {
    5.             Debug.Log(joystickName);
    6.         }
    7.  
    8.  
    9.         string[] names = Input.GetJoystickNames();
    10.         for (int x = 0; x < names.Length; x++)
    11.         {
    12.             print(names[x].Length);
    13.             if (names[x].Length == 19)
    14.             {
    15.                 return "PS4";
    16.             }
    17.             if (names[x].Length == 33)
    18.             {
    19.                 return "XBOX";
    20.             }
    21.         }
    22.  
    23.         return "UNKNOWN";
    There are a few questions of have about this.

    Firstly, for the joystickName it simply includes the word "Xbox" in the controller name, so I'm tempted to just use if (joystickName.ToLower().Contains("xbox")) to try to detect any type of xbox controller.

    If so, where can I find what the Playstation controller is named? Where's the documentation that lists what Unity has internally named as different controllers? It clearly says in the controller names list for my Xbox controller "Controller (Xbox one for Windows)", but I don't have a Playstation controller around to test right now so I don't know what Unity is going to use as a name for the Playstation controller...

    Secondly, I'm not understanding the whole idea that a playstation 4 controller is always at the 19th position in joystick names? And the Xbox is 33? What are these ids? I can't seem to find them anywhere in any of the documentation, any list of controllers.
     
  2. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    What I do is just give the user an option in the settings menu to select the button icons. Mainly because PlayStation controller drivers have been awful and although they are getting better, a number of gamers use Xbox emulation apps for their ds4's and ds3's. That is also due to a number of games not supporting ps controllers at all. Even steam has an internal system to emulate Xbox pads when using dual shock controllers. So even if you go to the trouble of detecting the controller, they may end up with Xbox icons anyway.
     
    Ignacii and astracat111 like this.
  3. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    685
    @WarmedxMints

    Thanks Mints. I found the profiles within the InControl documentation.

    I used the following for the time being. The unfortunate limitation, but something on PC that you just have to deal with, is detecting whether there's a controller INITIALLY connected...it isn't really possible from what I can see, but you can just alert the user that a controller is required.

    I'm using InControl ($35 but WELL worth it):

    //Firstly
    Code (CSharp):
    1. using InControl;
    2. using UnityEngine.UI;
    //Then hook up an image in the inspector:
    Code (CSharp):
    1.     public Image controllerUnpluggedImage;
    //Have a public enum you can grab from your script:
    Code (CSharp):
    1.     public enum ControllerTypeConnected { Xbox, Playstation, Other }
    2.     [HideInInspector]
    3. public ControllerTypeConnected controllerTypeConnected;
    //On 'Start':
    Code (CSharp):
    1.         // --- InControl
    2.         InputManager.OnDeviceDetached   += ControllerDisconnected;
    3.         InputManager.OnDeviceAttached   += ControllerConnected;
    Code (CSharp):
    1.     private void ControllerDisconnected(InputDevice inputDevice)
    2.     {
    3.         controllerUnpluggedImage.gameObject.SetActive(true);
    4.     }
    Code (CSharp):
    1.     private void ControllerConnected(InputDevice inputDevice)
    2.     {
    3.         controllerUnpluggedImage.gameObject.SetActive(false);
    4.  
    5.         if (getControllerType() == "XBOX")
    6.         {
    7.             controllerTypeConnected = ControllerTypeConnected.Xbox;
    8.             UnityEngine.Debug.Log("You connected an xbox controller!");
    9.         }
    10.         else if (getControllerType() == "PS")
    11.         {
    12.             controllerTypeConnected = ControllerTypeConnected.Playstation;
    13.             UnityEngine.Debug.Log("You connected a playstation controller!");
    14.         }
    15.         else
    16.         {
    17.             controllerTypeConnected = ControllerTypeConnected.Other;
    18.         }
    19.     }
    Code (CSharp):
    1.   private string getControllerType()
    2.     {
    3.         string[] joystickNames = Input.GetJoystickNames();
    4.  
    5.         foreach (string joystickName in joystickNames)
    6.         {
    7.             if (joystickName.ToLower().Contains("xbox"))
    8.             {
    9.                 return "XBOX";
    10.             }
    11.             else if (joystickName.ToLower().Contains("playstation"))
    12.             {
    13.                 return "PS";
    14.             }
    15.             else
    16.             {
    17.                 return "OTHER";
    18.             }
    19.         }
    20.         return "OTHER";
    21.     }
     
    comandogdev and steve-runwildent like this.
  4. Ignacii

    Ignacii

    Joined:
    May 23, 2013
    Posts:
    56
    Really good idea! Thanks! I might as well do the same.
     
  5. dr4

    dr4

    Joined:
    Jan 14, 2015
    Posts:
    93
    thanks for the code @astracat111 , I was looking for something to get the user controller, just a small update that may help simplify things a bit:


    Code (CSharp):
    1.         private string getControllerType()
    2.         {
    3.             string joystickName = Input.GetJoystickNames().First();
    4.  
    5.             if (joystickName.ToLower().Contains("xbox"))
    6.             {
    7.                 return "XBOX";
    8.             }
    9.             else if (joystickName.ToLower().Contains("playstation"))
    10.             {
    11.                 return "PS";
    12.             }
    13.             else
    14.             {
    15.                 return "OTHER";
    16.             }
    17.         }
     
    Last edited: Aug 16, 2021
    astracat111 likes this.
  6. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    685
    Yes and then the annoying part is switching out graphics per controller, but thanks to incontrol it is possible.