Multi-touch

Hey everyone. This is my first post on the forums, getting my feet wet with Unity iPhone - really enjoying it thus far. I’ve looked through a lot of posts, the FAQ post at the top of this forum as well, and haven’t found a working solution to what I’m trying to do. It’s quite simple on paper, implementation for me right now is what is keeping me scratching my head.

How do I simply get a 2D Texture of mine to scale it’s Height and Width depending on multitouch, that’s simply all I’m looking for. The Scripting Reference isn’t much help to me so far either with this issue.

function Update()
{
	if ( iPhoneInput.touchCount == 2 ) 
   	{ 
      var touch1 : iPhoneTouch = iPhoneInput.GetTouch( 0 ); 
      var touch2 : iPhoneTouch = iPhoneInput.GetTouch( 1 ); 
        
      if ( touch1.position.x < touch2.position.x ) 
         Brayden.width -= ( touch1.deltaPosition.x - touch2.deltaPosition.x ) / 10; 
      if ( touch1.position.x > touch2.position.x ) 
         Brayden.width += ( touch1.deltaPosition.x - touch2.deltaPosition.x ) / 10;
        
      if ( touch1.position.y < touch2.position.y ) 
         Brayden.height -= ( touch1.deltaPosition.x - touch2.deltaPosition.x ) / 10;
      if ( touch1.position.y > touch2.position.y ) 
         Brayden.height += ( touch1.deltaPosition.x - touch2.deltaPosition.x ) / 10;
 	} 
	
}

Any help would be greatly appreciated! I could be far off base with my small attempt at this, any direction would help though.

Thanks,
Brayden

Hi, welcome to the forum!

If you mean the pinch/spread movement, the key thing is the changing distance between the two fingers. Since the points are Vector2s, you can use Vector2.Distance on the two points to determine this. Basically, you should record the distance between the fingers on the first frame where the two fingers are touching. Then, on each subsequent frame, get the distance again and divide it by the initial distance. The resulting value is the fraction of the initial distance that is now between the two fingers - this is your scale value. You can change the scale of the texture object or move the camera in and out to perform the scaling onscreen.

Thanks Andeeee!

Finally I’m starting to understand a little more about how touch works. Now you’ve mentioned using Vector2.Distance, which I looked that up in the Scripting Reference and it looks like what I should be using, you’re right.

However, you mentioned “recording” the touch and movements. Do you mean within the IF statement, putting some sort of statement of the two touch points in Vector2. I guess a better way of asking is… how would it roughly be implemented into code, a basic idea or pseudo code would do so you don’t even have to cheat and give me an answer :wink: Any information would be great.

Thanks,
Brayden

So far I’ve been working trying to implement it, reading through documents and stuff.

Vector2 currentDistance  = touch1.position - touch2.position;
Vector2 previousDistance = (touch1.position - touch1.deltaPosition) - (touch2.position - touch2.deltaPosition);

Does someone by chance have a pre-made script I can learn from? Really I’m interested in learning if at all possible, a nudge further works for me. But sample codes or examples always help as well.

And this (following code) is the GUI script and element I’m trying to make scale it’s height and width with the multi-touch:

function OnGUI()
{
	//Show image of Brayden
	GUI.Label(Rect(Screen.width/2 + 2- Brayden.width/2,Screen.height/2 - Brayden.height/2,320,480), GUIContent(Brayden));
}

Thanks guys!

I suppose the word “record” was a bit vague, really.

What I had in mind was storing the distance between the points in a variable as soon as two touches are detected:-

var distBetweenTouches: float;
var twoTouches: boolean;

function OnGUI() {
    ...
    if ((iPhoneInput.touchCount > 1)  !twoTouches) {
        twoTouches = true;
        distBetweenTouches = Vector2.Distance(iPhoneInput.touches[0], iPhoneInput.touches[1]);
    }
    ...
}

Then, on each subsequent call, you would measure the new distance between the touches and divide it by the original distance:-

var scaleFactor: float = 1;
if (twoTouches) {
    var newDist = Vector2.Distance(iPhoneInput.touches[0], iPhoneInput.touches[1]);
    scaleFactor = newDist / distBetweenTouches;
    ...
}

The scale factor value is actually the scale relative to the scale at the time when the pinch/spread started with the two touches. Basically, you take that original scale value and further scale it up or down by the new scale factor.

I feel like it’s almost there, unfortunately running into an error message that I can’t get around. I’ve been fiddling around with this code for about 2 hours tonight and still unsuccessful. Maybe you can push me through this last, hopeful, part - so I can achieve basic pinch/zoom feature for doing this on an image.

Once this is complete maybe I’ll have a much better understanding of the code and process, and I can assist people in the future by writing a tutorial on how to do simple snippets like such, and create a tutorial library for basic things - as I learn too.

Anyways following is both the error message, first, and the code, second. Any ideas or suggestions is once again welcome. And I thank you sooooo much for helping me so far Andeeee!

Error Message:

IndexOutOfRangeException: Array index is out of range.

*Seems to me pretty self explanatory, and I’ve tried different alternatives. The error message seems to be pointing to the following line thus far:

var pos1 : Vector2 = iPhoneInput.touches[0].position;

I tried changing it up, adding values to it to bring it in range hopefully but no solution.

Code:

var distBetweenTouches : float; 
var twoTouches: boolean;
var Brayden : Texture2D; 

var BraydenWidth : float = 1;
var BraydenHeight : float = 1;
	
var pos1 : Vector2 = iPhoneInput.touches[0].position; 
var pos2 : Vector2 = iPhoneInput.touches[1].position;

function OnGUI() 
{ 	
	GUI.Label(Rect(Screen.width/2 + 2- Brayden.width/2,Screen.height/2 - Brayden.height/2,BraydenWidth,BraydenHeight), GUIContent(Brayden));
    
    
    if ((iPhoneInput.touchCount > 1)  !twoTouches) 
    { 
        twoTouches = true; 
        distBetweenTouchs = Vector2.Distance( pos1, pos2 ); 
    } 
    
}


function Update()
{	
	var scaleFactor: float = 1; 
	
	if (twoTouches) 
	{ 
		var newDist : float = Vector2.Distance( pos1, pos2 ); 
		
    	scaleFactor = newDist / distBetweenTouches; 
    	BraydenWidth  = scaleFactor / BraydenWidth;
    	BraydenHeight = scaleFactor / BraydenHeight;
	}
	
}

This is all the code so far in my JS script file titled GUI_Main. Maybe someone has a better chance at it than I do, I admit I’m a beginner with Unity. Got to start somewhere I suppose.

Thanks - this is a helpful place so far!
Brayden

You need to set the values of pos1 and pos2 inside the ‘if’ statement:-

function OnGUI() 
{
    if ((iPhoneInput.touchCount > 1)  !twoTouches) 
    { 
        var pos1 : Vector2 = iPhoneInput.touches[0].position; 
        var pos2 : Vector2 = iPhoneInput.touches[1].position; 

        twoTouches = true; 
        distBetweenTouchs = Vector2.Distance( pos1, pos2 ); 
    }
    ...
}

Basically, this is saying “if there are at least two touches, then get the distance between the first two”. If you try to get the touches when you haven’t established they exist, you will get the index-out-of-range error.