Finding the centre of two touches

Hello all, today i’m creating a pinch rotate script for my 2d sprite based game, now, i know i need to do the following:

  1. Check if two fingers are touching
  2. Find the centre of these two touches
  3. Cast a ray
  4. Does the ray hit a rigid body?
  5. If so, the rigid body can be rotated

I’ve already done the majority of it, but whats the best way to find the centre of two touches? Bearing in mind its 2D and all objects are on a fixed Z Plane…

Any help would be appreciated, cheers. :slight_smile:

var touch1 : Vector3;
var touch2 : Vector3;

var center = (touch1 + touch2) / 2;

It doesn’t matter if it’s 2d or 3d when they are at the same z pos.

Well I’m no expert but Input.touches returns an array of all touches. It stores the position of each touch also. If you’re positive that the first two touches will always be a pinching gesture you could do something like:

Vector3 center = Input.touches[0].position - Input.touches[1].position;

It would be best not to hard code the array indexes, but that could change depending on your setup. For example in your method before the pinch gesture you could get the Input.touchCount value and then get count+1 and count+2 for the pinch. Something like this could help in the case where you have other buttons/touches going on at the same time.

For the raycast, just after you find the center Vector3 setup Ray and RaycastHit objects then call Physics.Raycast()

Depending on your setup you’ll want to use different overloads for this. For example if it is possibly to hit multiple colliders and you don’t want to exclude any colliders from being hit then you could do Physics.RaycastAll() which returns a RaycastHit for you. If there’s some colliders that you don’t want to be a part of that raycast, there are overloads for layers in Physics.Raycast()

The RaycastHit stores the rigidbody so it can be rotated that way.

Something like this:

void Update()
	{
		int touchCount = Input.touchCount;
		Touch[] touches = Input.touches;
		if(touchCount >= 2)
		{
			Vector2 center = touches[touchCount-1].position - touches[touchCount].position;
			
			Ray ray = Camera.main.ScreenPointToRay(center);
			RaycastHit hit;
			if(Physics.Raycast(ray, out hit))
				hit.rigidbody.rotation = new Quaternion(0,0,0,0);
		}
	}

However, I recommend splitting that up into separate functions so you can reuse them with other things:

void Update()
{
	int touchCount = Input.touchCount;
	Touch[] touches = Input.touches;
	if(touchCount >= 2)
	{
		RotateRigidBody(CastRay(touches[touchCount-1].position - touches[touchCount].position).rigidbody);
	}
}

RaycastHit CastRay(Vector2 point)
{
	Ray ray = Camera.main.ScreenPointToRay(point);
	RaycastHit hit;		
			
	if(Physics.Raycast(ray, out hit))
		return hit;
	else
		return null;
}

void RotateRigidBody(Rigidbody body)
{
	rigidbody.rotation = new Quaternion(0,0,0,0);		
}

Vector3 FindCenter(Vector3 position1, Vector3 position2)
{
	return position1 - position2;
}

One other thing that could make it slightly more efficient is recording when the user does a pinch and call it through a function instead of in Update() this also would ensure that you’re getting the right Touch objects from the Input.touches array.

I hope this helps.