Search Unity

Unity iOS multitouch problem (3rd touch added after 2 touches)

Discussion in 'Immediate Mode GUI (IMGUI)' started by MatRon, Aug 15, 2011.

  1. MatRon

    MatRon

    Joined:
    Jan 14, 2011
    Posts:
    16
    Hi community,
    i am experiencing a strange behavior with multitouch: when you touch with 2 fingers, there's a touch event added just in the middle of the 2 touches.
    For example, i have a GUI.Button on the screen, if i touch with one finger 1 inch on top, and the other finger 1 inch below, it will TAP THE BUTTON! It seems that it's adding another touch just in between the 2 original ones.
    Has anyone experienced something similar? and, if yes, how should i fix it?
    Thanks a lot!

    Mat
     
  2. DanjelRicci

    DanjelRicci

    Joined:
    Mar 8, 2010
    Posts:
    310
    Has this problem been solved? I'm experiencing it right now with Unity 4.1.0f4 Pro. Haven't found yet a workaround for this.
     
  3. nitishk

    nitishk

    Joined:
    Mar 23, 2013
    Posts:
    10
    Unity's built in GUI system does not support multitouch and it is very slow on mobile platforms due to the number of drawcalls it produces. You would be better off using a 3rd party tool like NGUI.
     
  4. col000r

    col000r

    Joined:
    Mar 27, 2008
    Posts:
    699
    Unity is cheating. UnityGUI doesn't support multitouch, it uses the average position of all your fingers and puts the invisible mouse-cursor right there. I reported this as a bug even before Unity 3 was out, complained about it on the beta list for ages, but apparently no one cares...
     
  5. DanjelRicci

    DanjelRicci

    Joined:
    Mar 8, 2010
    Posts:
    310
    That's ridiculous.
    I'm pretty sure this problem somehow popped up even using Rect.Contains with single Touch IDs instead of GUI Buttons, but I have to check it again.

    I'd like to make one of my games compatible with this Arcadie thing: it uses multitouch to pass the controls to the iPhone, but with GUI Buttons it just makes a big mess, detecting random inputs whenever I press two or more buttons on the Arcadie unit.

    I'm going to try Rect.Contains now, let's see...


    EDIT: it went better than expected, I am able to track individual touch positions without any interferences, using Rect.Contains.

    Since I wrote my code for the Arcadie unit, I'm pasting here my whole script for those who have one, or for those who want to figure out some multitouch. It's really easy, just add it to an empty project, attach it to the MainCamera, then build and run on iPhone/iPod Touch: it just works (tested on iPhone 4S, but I made it also compatible with non-retina screens).

    Notice that every frame this code runs an individual foreach cycle for every button of the Arcadie unit (there are six). It's not the most performant solution in my opinion, but actually I have no other ideas on how to do it, so I guess it's just fine (unless you want to optimize drastically everything in your code).

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class ArcadieControl : MonoBehaviour {
    6.    
    7.     //Divider used to resize all input elements to retina and non-retina size
    8.     float HD = 0.5f;
    9.    
    10.     //Init of all the rects
    11.     Rect LEFT_rect = new Rect (0,0,0,0);
    12.     Rect DOWN_rect = new Rect (0,0,0,0);
    13.     Rect AA_rect = new Rect (0,0,0,0);
    14.     Rect UP_rect = new Rect (0,0,0,0);
    15.     Rect RIGHT_rect = new Rect (0,0,0,0);
    16.     Rect BB_rect = new Rect (0,0,0,0);
    17.    
    18.     //Init of all the buttons
    19.     public static bool LEFT_active = false;
    20.     public static bool DOWN_active = false;
    21.     public static bool AA_active = false;
    22.     public static bool UP_active = false;
    23.     public static bool RIGHT_active = false;
    24.     public static bool BB_active = false;
    25.    
    26.     void Start () {
    27.        
    28.         //Enables multitouch and disables screen timeout (you can't reach the
    29.         //unlock slider when the iPhone is inside the Arcadie unit)
    30.         Input.multiTouchEnabled = true;
    31.         Screen.sleepTimeout = SleepTimeout.NeverSleep;
    32.        
    33.         //If screen is not Retina, sets the didiver to one
    34.         if (Screen.width < 500)
    35.             HD = 1;
    36.        
    37.         //Updates all the rects after having found the resolution divider
    38.         UpdateRects();
    39.     }
    40.    
    41.     void UpdateRects () {
    42.        
    43.         //Sets the size of all the rects
    44.         //TOP ROW
    45.         LEFT_rect = new Rect ( 0, 320/HD, Screen.width/3, 80/HD );
    46.         DOWN_rect = new Rect ( Screen.width/3, 320/HD, Screen.width/3, 80/HD );
    47.         AA_rect = new Rect ( (Screen.width/3)*2, 320/HD, Screen.width/3, 80/HD );
    48.         //LOWER ROW
    49.         UP_rect = new Rect ( 0, 400/HD, Screen.width/3, 80/HD );
    50.         RIGHT_rect = new Rect ( Screen.width/3, 400/HD, Screen.width/3, 80/HD );
    51.         BB_rect = new Rect ( (Screen.width/3)*2, 400/HD, Screen.width/3, 80/HD );  
    52.     }
    53.  
    54.     void Update () {
    55.        
    56.         //Finds all the touches. Each button has its individual foreach cycle,
    57.         //so it can work indipendently from the other buttons
    58.        
    59.         UP_active = false;
    60.         foreach (Touch T in Input.touches){
    61.             if (UP_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
    62.                 UP_active = true;
    63.                 break;
    64.             }
    65.         }
    66.        
    67.         DOWN_active = false;
    68.         foreach (Touch T in Input.touches){
    69.             if (DOWN_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
    70.                 DOWN_active = true;
    71.                 break;
    72.             }
    73.         }
    74.        
    75.         LEFT_active = false;
    76.         foreach (Touch T in Input.touches){
    77.             if (LEFT_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
    78.                 LEFT_active = true;
    79.                 break;
    80.             }
    81.         }
    82.        
    83.         RIGHT_active = false;
    84.         foreach (Touch T in Input.touches){
    85.             if (RIGHT_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
    86.                 RIGHT_active = true;
    87.                 break;
    88.             }
    89.         }
    90.        
    91.         AA_active = false;
    92.         foreach (Touch T in Input.touches){
    93.             if (AA_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
    94.                 AA_active = true;
    95.                 break;
    96.             }
    97.         }
    98.        
    99.         BB_active = false;
    100.         foreach (Touch T in Input.touches){
    101.             if (BB_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
    102.                 BB_active = true;
    103.                 break;
    104.             }
    105.         }
    106.     }
    107.    
    108.     void OnGUI () {
    109.        
    110. #if UNITY_EDITOR
    111.         //These GUI buttons do nothing, they are just used to match
    112.         //the correct placement of the Arcadie rubber tips. They are
    113.         //not shown on iPhone (in fact they are also hidden by the Arcadie unit)
    114.         GUI.Button(LEFT_rect,"LEFT");
    115.         GUI.Button(RIGHT_rect,"RIGHT");
    116.         GUI.Button(UP_rect,"UP");
    117.         GUI.Button(DOWN_rect,"DOWN");
    118.         GUI.Button(AA_rect,"AA");
    119.         GUI.Button(BB_rect,"BB");
    120. #endif
    121.        
    122.         //Shows a different string for each pressed button, just for some on-screen debug
    123.         if (LEFT_active == true)
    124.             GUI.Label(new Rect(10/HD,15/HD,250/HD,40/HD),"Pressed LEFT");
    125.         if (RIGHT_active == true)
    126.             GUI.Label(new Rect(10/HD,45/HD,250/HD,40/HD),"Pressed RIGHT");
    127.         if (UP_active == true)
    128.             GUI.Label(new Rect(10/HD,75/HD,250/HD,40/HD),"Pressed UP");
    129.         if (DOWN_active == true)
    130.             GUI.Label(new Rect(10/HD,105/HD,250/HD,40/HD),"Pressed DOWN");
    131.         if (AA_active == true)
    132.             GUI.Label(new Rect(10/HD,135/HD,250/HD,40/HD),"Pressed A");
    133.         if (BB_active == true)
    134.             GUI.Label(new Rect(10/HD,165/HD,250/HD,40/HD),"Pressed B");
    135.     }
    136. }
    137.  
     
    Last edited: Jun 8, 2013
  6. atmuc

    atmuc

    Joined:
    Feb 28, 2011
    Posts:
    1,166
    is there any workaround for this?
     
  7. jdesantos

    jdesantos

    Joined:
    May 24, 2013
    Posts:
    312