Unusual multitouch behavior (Android)

Hi, I’m hoping someone can help shed some light on this problem I’ve been trying to solve over the past couple of days with no luck.

So the idea is that I’m trying to detect multiple touches on an Android device with the purpose being for each touch to move its’ own gameobject. The problem I am encountering is that when I have 2 touches, and the 1st touch ends/cancels, the 2nd touch also seems to stop with it, what’s weirder is that as soon as I initiate another (originally 1st) touch, the 2nd touch that did not end will suddenly continue to move the gameobject just fine.

This is a rough/simplified representation of the code I have:

public class TrackerHandlerScript : MonoBehaviour {
	
	public static GameObject[] trackerArray = new GameObject[2];

	private int _tapCount;
	
	private Object trackerPrefab;
	// Use this for initialization
	void Start () {
		trackerPrefab = Resources.Load("Prefabs/prefab_tracker");
	}
	
	// Update is called once per frame
	void Update () {
		_tapCount = Input.touchCount;
		if(_tapCount > 0 ){
			for(int i = 0; i < _tapCount; i++){
				if(Input.GetTouch(i).phase == TouchPhase.Began){
					createTracker(i, Input.GetTouch(i).fingerId);
				}
			}
		}
	}
	
	void createTracker(int idx, int id = 0){
	   if(trackerArray[idx] != null){
	   	   Destroy(trackerArray[idx] .gameObject);
	   }
	   trackerArray[idx] = Instantiate(trackerPrefab, Vector3.zero, Quaternion.identity) as GameObject;
	   trackerArray[idx] .GetComponent<TrackerScript>().touch = id;
	}
}

The idea here is that I store my 2 gameobjects in an array and only instantiate a tracker into an empty index. This seems to be working as intended.

This is the logic in the gameobject’s script that handles the touch:

public class TrackerScript : MonoBehaviour {
    public int idx;
    public int touch;
    Vector3 pos;
	void Update () {
		for(int i = 0; i < Input.touchCount; i++){
			if(Input.GetTouch(i).fingerId == touch){
				if(Input.GetTouch(i).phase == TouchPhase.Ended || Input.GetTouch(i).phase == TouchPhase.Canceled){
					Destroy(gameObject);
				}
			}
		}
		for(int i = 0; i < Input.touchCount; i++){
			if(Input.GetTouch(i).fingerId == touch){
				pos = Input.GetTouch(i).position;
			}
		}
		_transform.position = Camera.main.ScreenToWorldPoint(pos)
	}
}

So no syntax errors or anything (in case I made a typo or left anything out). The idea here is that I use the passed fingerId from the handler to identify the touch and only move the gameobject if it’s a match. Releasing the touch will destroy the gameobject thus nullifying the index for the tracker array.

Once again, if anyone has any idea what might be wrong with this code/logic, I’m all ears.

P.S. I am on Unity 4.6.3f for full disclosure.

edit: updated some of the code.

the second stops because your for loop iterates only as often as fingers on the screen, leaving touch 2 out after you removed whatever finger.
you must not bind the finger id to their initial touch index, but check them all against however many touched you have.

I managed to resolve the issue.

For anyone who’s curious, it is mainly with how Unity handles touches, I had to centralize what I did with the touches all in one place in order to maintain the correct touch indexes.

Yeah, just printed a long list of debug.logs to figure out the issue myself. Unity handles touch in a weird manner.

So if put your first finger, say on a blue object, it will have touchIndex (in Input.GetTouch(index)) of “0” and then if you put your second finger, say on an orange obj, it will have a touch index of “1”. Now obviously when you lift any of the finger, whether 0 or 1 (blue or orange), the remaining touch will have the index of “0”, which is not what I initially expected, but makes sense in an array. Fair enough.

So if the finger you lifted from the screen was your second finger (ie the one on orange obj) and put it back on the screen, it will have once again touch index of “1”. But if you lifted your first finger (ie the one on blue obj), and put it back on, you would expect the new finger to have the index of “1”, but it will have an index of “0” in the array, and the finger on orange will have index of “1”, even tho when it was single touch it had an index of “0”, it will be changed. THIS caused my objects swap positions quickly when I lifted my finger from one object. But not if it was second finger that was being lifted. Took me quite some time to figure it out, maybe next time I will use fingerID, or heck make alternate script that uses fingerID. Correct me tho if this is not how it works.

Just putting my encounter with an issue out there if someone had this issue with Unity’s touches and didn’t know how touches function in multi-touch situation in Unity.