Search Unity

Pressing multiple (arrow) buttons simultaneously on mobile

Discussion in 'Android' started by deLord, Feb 11, 2019.

  1. deLord

    deLord

    Joined:
    Oct 11, 2014
    Posts:
    306
    OK guys, I cannot believe there needs to be a thread about this but this seems to be reality :D
    I searched for hours in the docs, YT videos and tried all sorts of different code myself, including abusing standard assets ;)

    How can I have a regular set of 4 arrow keys on my mobile device on which I can have multiple (2 is fine) buttons pressed at once? No matter what I try, on my Android only one button can ever be pressed at the same time.

    I just need 4 regular buttons to control the movement of my player, that's all. I even tried using the virtual Joysticks but this type of input method doesnt work well for my game (as I always need to drag the handle from where it is, not good).
     
  2. deLord

    deLord

    Joined:
    Oct 11, 2014
    Posts:
    306
    This is the hardcore method which I would 100% expect to work but still it doesnt (properly):
    Code (CSharp):
    1. // inside the Update method
    2.             bool left = false;
    3.             bool up = false;
    4.             bool down = false;
    5.             bool right = false;
    6.             if (Input.touches.Length > 0) {
    7.                 foreach (Touch touch in Input.touches) {
    8.                     if (__leftBtnRect.Contains(touch.position)) left = true;
    9.                     else if (__upBtnRect.Contains(touch.position)) up = true;
    10.                     else if (__downBtnRect.Contains(touch.position)) down = true;
    11.                     else if (__rightBtnRect.Contains(touch.position)) right = true;
    12.                 }
    13.                 if (left || right || down || up) debugText.text = (up?"UP":"") + "/" + (down?"DOWN":"") + "/" + (left?"LEFT":"")+ "/" + (right?"RIGHT":"");
    14.             } else {
    15.                 debugText.text = "No";
    16.             }
    How can this not work? Most of the time, Unity just registers one of the touches. In ~5% of cases, I can move diagonally as expected. And what always seems to work for absolutely no apparent reason is that I can always press left+right at the same time.

    Super strange phenomenon: later in that method I also add another thing for debugging purposes.
    Code (CSharp):
    1. debugText.text += myRigidBody.velocity;
    I get the following output (sometimes) when pressing 2 "buttons"
    "No (0,0, 0,0) (0,0, 0,0) (0,0, 0,0) (0,0, 0,0) (0,0, 0,0) (0,0, 0,0) [...]" (continues the longer I hold the "buttons")
    This can only occur if NO input on my Rects is registered at all. But I hold 2 freaking fingers on my phone :'(
    It does always work with 1 button, so we are not talking about hardware issues imo
     
    Last edited: Feb 11, 2019
  3. deLord

    deLord

    Joined:
    Oct 11, 2014
    Posts:
    306
    OK here is what happened and how I solved it:

    My phone (720 x 1280 pixels) doesnt seem to register when two touches are too close to each other.
    The way I came up with is the following:

    There are 6 Rects being drawn scriptwise. The player can now either tap the intersection between two or he can use the opposite side (e.g. touch right + up(left side)). This seems to work as expected.

    epicControls.png

    Code (CSharp):
    1.     void Start () {
    2.         // Set up the 6 virtual buttons
    3.         float btnHeight = Screen.height * 0.3f;
    4.         float btnWidth = Screen.height * 0.3f;
    5.         float offsetY = Screen.height * 0.1f;
    6.         __upLeftBtnRect =    new Rect(0, offsetY + btnHeight *1.8f,  btnWidth, btnHeight);
    7.         __leftBtnRect =      new Rect(0, offsetY + btnHeight *0.9f,  btnWidth, btnHeight);
    8.         __downLeftBtnRect =  new Rect(0, offsetY,                      btnWidth, btnHeight);
    9.         __upRightBtnRect =   new Rect(Screen.width-btnWidth, offsetY + btnHeight * 1.8f, btnWidth, btnHeight);
    10.         __rightBtnRect =     new Rect(Screen.width-btnWidth, offsetY + btnHeight * 0.9f, btnWidth, btnHeight);
    11.         __downRightBtnRect = new Rect(Screen.width-btnWidth, offsetY, btnWidth, btnHeight);
    12.     }
    13.  
    14.     void Update () {
    15.         if (hp > 0) {
    16.             bool left = false;
    17.             bool up = false;
    18.             bool down = false;
    19.             bool right = false;
    20.             if (Input.touches.Length > 0) {
    21.                 foreach (Touch touch in Input.touches) {
    22.                     if (__leftBtnRect.Contains(touch.position)) left = true;
    23.                     if (__upLeftBtnRect.Contains(touch.position)) up = true;
    24.                     else if (__downLeftBtnRect.Contains(touch.position)) down = true;
    25.                     if (!left && __rightBtnRect.Contains(touch.position)) right = true;
    26.                     if (!up && __upRightBtnRect.Contains(touch.position)) up = true;
    27.                     if (!down && __downRightBtnRect.Contains(touch.position)) down = true;
    28.                 }
    29.                 if (left || right || down || up) debugText.text = (up ? "UP" : "") + "/" + (down ? "DOWN" : "") + "/" + (left ? "LEFT" : "") + "/" + (right ? "RIGHT" : "");
    30.             }
     
    Last edited: Feb 12, 2019
  4. MichelPlante

    MichelPlante

    Joined:
    Feb 8, 2018
    Posts:
    1
    Thank you so much for your work! I'll give it a try next week! I'll have to implement it with a jump button as well! I'm very happy that you shared your work! It's sincerely appreciated! Thanks!