iOS multiTouch / release - Strange problem

Hello.
I am having weird problem with multi touching and releasing 3D objects on the iOS.
Below is an explanation, thanks if advance for the help :slight_smile:

Short explanation:
I am trying to have few objects, that shoud start spinning when i touch / hold on them and stop when i release them. Problem is that if i multi touch few objects and release them in the same order of touching, only the first object stops, the other 2 continue spinning…

The scripts were written this way, because the game was initially made for PC/MAC and i preffer to keep the OnMouseDown / Up functions and just call them with the touch…

→ In my example camera is facing Z-Forward

I will try to explain as best as possible what is happening with a real example.

1: Create (say) 4 cubes. Move them infront camera and add BoxCollider with trigger ON…

2: Add that script to each of the cubes:

#pragma strict

// Public Variables
public var startRotateSmooth	: float;     // Smoothly start spinning
private var minRotateSpeed		: float;     // the minSpeed before it stops
public var maxRotateSpeed		: float;     // max speed to stop accelerating

// Private Variables
private var spinSpeed		: float;
private var startSpin		: boolean;
private var trans			: Transform;

function Start () 
{
	trans = this.transform;
	startRotateSmooth = 20;
	minRotateSpeed = 0.5;
	maxRotateSpeed = 15;
	startSpin = false;
}

function Update () 
{
	if (startSpin)					
	{		
		spinSpeed += Time.deltaTime * startRotateSmooth;			// Start the spin smoothly
		if (spinSpeed >= maxRotateSpeed)							// If the smoothStart exceed the max speed = maxRotateSpeed
		{
			spinSpeed = maxRotateSpeed;		
		}
	}
	
	else if(!startSpin)					
	{
		spinSpeed -= Time.deltaTime * startRotateSmooth;	
		if (spinSpeed <= minRotateSpeed)		
			spinSpeed = 0;					
	}
	trans.Rotate(Vector3.back * -spinSpeed); 
}

function OnMouseDown()
{
	startSpin = true;
}

function OnMouseUp()
{
	startSpin = false;
}

3: Add that script to the camera:

#pragma strict

// Private variables
private var objectTouched : GameObject[];			// Array to store the touched objects to
objectTouched = new GameObject[6];					// Make the array 6 elements
 
function Update () 
{
	// Code for OnMouseDown in the iPhone. Unquote to test.
	var hit : RaycastHit;
	for (var i = 0; i < Input.touchCount; ++i) 
	{
		if (Input.GetTouch(i).phase == TouchPhase.Began) 
		{
			// Construct a ray from the current touch coordinates
			var ray = camera.ScreenPointToRay (Input.GetTouch(i).position);
			if (Physics.Raycast (ray,hit)) 
			{
				objectTouched *= hit.transform.gameObject;			// Store the touched object in an array*

_ objectTouched*.SendMessage(“OnMouseDown”); // Send message to the touched object to OnMouseDown / Start*_
* }*
* }*

* if (Input.GetTouch(i).phase == TouchPhase.Ended || Input.GetTouch(i).phase == TouchPhase.Canceled)*
* {*
_ objectTouched*.SendMessage(“OnMouseUp”); // Send message to the stored object to OnMouseUp / Stop*
* }
}
}
4: Start the game on iOS devide and touch few of the objects in a exact way:
→ 1: Touch one object, then addTouch second one, then addTouch third one.
→ 2: Release the first touched object, release the second touched object, release the third touched object - You shoud release in the order the object was touched.
5 - Only the first object stops, the second, 3rd are continue spinning. Attached is an image showing the way of touching if the explanation is confusing…
I am guessing that the problem is with the assignment of the objets in the array, but i can’ t find what is causing it…
[9902-multitouch_release.jpg*
|9902]_

Ah! So here’s your problem…

You make an array of 6 objects, and you are looping through the touchCount and assuming the touch index ‘i’ will align with your object index in your list. Not true. Touches is a dynamic list thats shifting based on when touches are added and removed.

EX:

touch 0 //touches=[t1]
object[0] = hitobject

touch 1 //touches=[t1,t2]
object[1] = hitobject

release 0 ////touches=[t2], removing touch 1 shifts touch2 to be at index 0
object[0].OnMouseUp()

release 0 //HERE! you remove the next touch, but the touch index is zero, not 1
object[0].OnMouseUp() //now you call mouseup on object 0 again, not object 1

Make sense?

Solutions are plentiful. But the obvious easy solution is to use a List instead of GameObject for holding your objects. Then call Add and Remove and the indices will align with the touches indices.

Hope this helps!