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

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

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.

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.

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…

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).

using UnityEngine;
using System.Collections;

public class ArcadieControl : MonoBehaviour {
	
	//Divider used to resize all input elements to retina and non-retina size
	float HD = 0.5f;
	
	//Init of all the rects
	Rect LEFT_rect = new Rect (0,0,0,0);
	Rect DOWN_rect = new Rect (0,0,0,0);
	Rect AA_rect = new Rect (0,0,0,0);
	Rect UP_rect = new Rect (0,0,0,0);
	Rect RIGHT_rect = new Rect (0,0,0,0);
	Rect BB_rect = new Rect (0,0,0,0);
	
	//Init of all the buttons
	public static bool LEFT_active = false;
	public static bool DOWN_active = false;
	public static bool AA_active = false;
	public static bool UP_active = false;
	public static bool RIGHT_active = false;
	public static bool BB_active = false;
	
	void Start () {
		
		//Enables multitouch and disables screen timeout (you can't reach the
		//unlock slider when the iPhone is inside the Arcadie unit)
		Input.multiTouchEnabled = true;
		Screen.sleepTimeout = SleepTimeout.NeverSleep;
		
		//If screen is not Retina, sets the didiver to one
		if (Screen.width < 500)
			HD = 1;
		
		//Updates all the rects after having found the resolution divider
		UpdateRects();
	}
	
	void UpdateRects () {
		
		//Sets the size of all the rects
		//TOP ROW
		LEFT_rect = new Rect ( 0, 320/HD, Screen.width/3, 80/HD );
		DOWN_rect = new Rect ( Screen.width/3, 320/HD, Screen.width/3, 80/HD );
		AA_rect = new Rect ( (Screen.width/3)*2, 320/HD, Screen.width/3, 80/HD );
		//LOWER ROW
		UP_rect = new Rect ( 0, 400/HD, Screen.width/3, 80/HD );
		RIGHT_rect = new Rect ( Screen.width/3, 400/HD, Screen.width/3, 80/HD );
		BB_rect = new Rect ( (Screen.width/3)*2, 400/HD, Screen.width/3, 80/HD );	
	}

	void Update () {
		
		//Finds all the touches. Each button has its individual foreach cycle,
		//so it can work indipendently from the other buttons
		
		UP_active = false;
		foreach (Touch T in Input.touches){
			if (UP_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
				UP_active = true;
				break;
			}
		}
		
		DOWN_active = false;
		foreach (Touch T in Input.touches){
			if (DOWN_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
				DOWN_active = true;
				break;
			}
		}
		
		LEFT_active = false;
		foreach (Touch T in Input.touches){
			if (LEFT_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
				LEFT_active = true;
				break;
			}
		}
		
		RIGHT_active = false;
		foreach (Touch T in Input.touches){
			if (RIGHT_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
				RIGHT_active = true;
				break;
			}
		}
		
		AA_active = false;
		foreach (Touch T in Input.touches){
			if (AA_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
				AA_active = true;
				break;
			}
		}
		
		BB_active = false;
		foreach (Touch T in Input.touches){
			if (BB_rect.Contains(new Vector2 (T.position.x, Screen.height-T.position.y))){
				BB_active = true;
				break;
			}
		}
	}
	
	void OnGUI () {
		
#if UNITY_EDITOR
		//These GUI buttons do nothing, they are just used to match
		//the correct placement of the Arcadie rubber tips. They are
		//not shown on iPhone (in fact they are also hidden by the Arcadie unit)
		GUI.Button(LEFT_rect,"LEFT");
		GUI.Button(RIGHT_rect,"RIGHT");
		GUI.Button(UP_rect,"UP");
		GUI.Button(DOWN_rect,"DOWN");
		GUI.Button(AA_rect,"AA");
		GUI.Button(BB_rect,"BB");
#endif
		
		//Shows a different string for each pressed button, just for some on-screen debug
		if (LEFT_active == true)
			GUI.Label(new Rect(10/HD,15/HD,250/HD,40/HD),"Pressed LEFT");
		if (RIGHT_active == true)
			GUI.Label(new Rect(10/HD,45/HD,250/HD,40/HD),"Pressed RIGHT");
		if (UP_active == true)
			GUI.Label(new Rect(10/HD,75/HD,250/HD,40/HD),"Pressed UP");
		if (DOWN_active == true)
			GUI.Label(new Rect(10/HD,105/HD,250/HD,40/HD),"Pressed DOWN");
		if (AA_active == true)
			GUI.Label(new Rect(10/HD,135/HD,250/HD,40/HD),"Pressed A");
		if (BB_active == true)
			GUI.Label(new Rect(10/HD,165/HD,250/HD,40/HD),"Pressed B");
	}
}

is there any workaround for this?

Yes, using a package that implements multitouch correctly.

http://forum.unity3d.com/threads/192064-NoesisGUI-XAML-based-User-Interface-RELEASED?p=1500735&viewfull=1#post1500735

:slight_smile: