Camera orbit around 3d object using swipe

Hello.

I am having a small trouble with camera orbiting in my game.

Camera is centered(!) on a cube and looks at this cube from above (about 30 degrees rotation) at fixed distance.
I want to make camera orbit player by swipe. I’ve drawn an image to help you understand what I want:

19330-rotation.png

Red line is a Vector2 screen cootrdinates (it’s how user swipes a screen for example)
Blue circle is how camera is orbiting cube.
If user touches screen at point A and swipes to point B, I want camera to rotate from point A1 to point B1.
Could you please help me with calculation of angles?

Thanks in advance.

I’ve found a solution. Every update I analyze if mouse left key is pressed an then I get mouse’s position. Then I substract it from center of the screen. This is my first vector.
Then I analyze position in previous update and substract it from center of the screen. This is my seond vector.
Then I use Vector2.Angle function to get an angle between these vectors.
The problem is that it’s always positive, and I cannot determine if user is swiping clockwise or counter-clockwise.
The saviour was Vector3.Cross function, which returned negative value if user is swiping clockwise.

Here’s full code of function that is called in Update when user presses mouse key

void Update () 
{
	OrbitAround();
}

void OrbitAround ()
{
	Vector2 screenCenter = new Vector2(Screen.width / 2, Screen.height / 2);
	Vector2 firstVector = lastFramePos - screenCenter;
	Vector2 convertedMouseInput = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
	Vector2 secondVector = convertedMouseInput - screenCenter;
	float angle = Vector2.Angle(firstVector, secondVector);
	Vector3 cross = Vector3.Cross(firstVector, secondVector);
     	if (cross.z < 0) {
		angle = -angle;
    	}
    	var rotation = Quaternion.Euler(0,  transform.rotation.eulerAngles.y + angle, 0);
    	transform.rotation = rotation;
}

I havent tested this with a touchScreen (none to hand right now), but this should in theory do what you need. You may need to adjust some of the public variables to get what you want precisely though:

using UnityEngine;
using System.Collections;

public class CameraTumble : MonoBehaviour
{
	// Attach this script to you camera
	// This script should likely be used in conjunction with a CameraLookAt script in unity's standard assets.
	// Script created by Alexander MacLeod - 14th December 2013

	public float tumbleSensitivity = 0.3f;		//NB. This value should be adjusted until a natural result is achieved. It affects the amount the camera will tumble around the object as a swipe takes place.
	public Transform pivotPoint;				//this should be the location the camera tumbles around
	public bool naturalMotion = true;			//this determines whether a left swipe will make the camera tumble clockwise or anticlockwise around the object

	private GameObject camParent;				//this will be the rotating parent to which the camera is attached. Rotating this object will have the effect of making the camera a specified location.
	private Vector2 oldInputPosition;			//records the position of the finger last update

	void Start ()
	{
		Transform originalParent = transform.parent;			//check if this camera already has a parent
		camParent = new GameObject ("camParent");				//create a new gameObject
		camParent.transform.position = pivotPoint.position;		//place the new gameObject at pivotPoint location
		transform.parent = camParent.transform;					//make this camera a child of the new gameObject
		camParent.transform.parent = originalParent;			//make the new gameobject a child of the original camera parent if it had one
	}
	
	// Update is called once per frame
	void Update ()
	{
		//TOUCH

		if (Input.touchCount > 0)
		{
				foreach (Touch touch in Input.touches)
				{
						if (touch.phase == TouchPhase.Began && touch.fingerId == 0)
						{
								oldInputPosition = touch.position;
						}
						if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary)
						{
								if (touch.fingerId == 0)
								{
										float xDif = touch.position.x - oldInputPosition.x;	//this calculates the horizontal distance between the current finger location and the location last frame.
										if (!naturalMotion){xDif *= -1;}
										if (xDif != 0){camParent.transform.Rotate (Vector3.up * xDif * tumbleSensitivity);}
										oldInputPosition = touch.position;
								}
						}
						if (touch.phase == TouchPhase.Ended && touch.fingerId == 0)
						{
							oldInputPosition = touch.position;
						}
				}
		}

		//MOUSE

		if (Input.GetMouseButtonDown(0))
		{
			oldInputPosition = Input.mousePosition;
		}
		if (Input.GetMouseButton(0))
		{
			float xDif = Input.mousePosition.x - oldInputPosition.x;
			if(!naturalMotion){xDif *= -1;}
			if(xDif != 0){camParent.transform.Rotate(Vector3.up * xDif * tumbleSensitivity);}
			oldInputPosition = Input.mousePosition;
		}
		if (Input.GetMouseButtonUp (0))
		{
			oldInputPosition = Input.mousePosition;
		}

	}
}

Untested idea:

a. Get the pixel positions where the user is touching the screen at A and B (from Input.touches)

b. Convert these to 3D worldspace coordinates (using ScreenToWorldPoint).

c. Use Vector3.Angle to calculate the angle between the vectors Cube->A and Cube-B (don’t know if your cube is at (0,0,0) or not, but easy to translate if not) - this is your Lα

d.) Then subtract α from the transform.rotation of the cube.