Rotating camera around the sphere

I’ve found a script that allows to rotate sphere with the mouse:
using UnityEngine;
using System.Collections;

public class SphereRotation : MonoBehaviour
{
    bool hasGrabbedPoint = false;
    Vector3 grabbedPoint;

    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            if (!hasGrabbedPoint)
            {
                hasGrabbedPoint = true;
                grabbedPoint = getTouchedPoint();
            }
            else
            {
                Vector3 targetPoint = getTouchedPoint();
                Quaternion rot = Quaternion.FromToRotation(grabbedPoint, targetPoint);
                transform.localRotation *= rot;
            }
        }
        else
            hasGrabbedPoint = false;
    }

    Vector3 getTouchedPoint()
    {
        RaycastHit hit;
        Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit);

        return transform.InverseTransformPoint(hit.point);
    }
}

However the thing I’m trying to achieve is a bit opposite - I’d like to rotate camera around the sphere, keeping the object still.
Could anyone help me a little bit with this?

Here is a solution. It is based on mouse movement as you indicated in your comment. To use it:

  • Go to Project Settings > Input and set ‘Type’ of movement to ‘Mouse Movement’ for both ‘Horizontal’ and ‘Vertical’.
  • Position the camera over the sphere looking at the sphere at the correct distance from the sphere.
  • Attach the following script to the camera.
  • Drag and drop the sphere onto the ‘sphere’ variable in the scrip in the Inspector.

#pragma strict
 
public var sphere : Transform;
public var speed = 1.0;

private var center : Transform;

function Start() {
	center = new GameObject().transform;
	center.parent = sphere;
	center.position = Vector3.zero;
	transform.parent = center;
}

function Update() {
	// if the sphere moves, uncomment the following line
	// center.position = sphere.position;
	
	if (Input.GetMouseButton(0))
		center.Rotate(-Input.GetAxis("Vertical") * speed, Input.GetAxis("Horizontal") * speed, 0.0);
}

Ok, so the idea is to rotate the camera together with the sphere, but you want to keep it from going crazy, so after rotating, you have to make sure that the mouse is touching exactly the same point it did before rotating, otherwise without moving the mouse any more, it will rotate again, because the grabbed position will appear to move even though you did not move the mouse.

So, what you could do, is keep the world position where the ray hit the sphere, and compare it to the world position where the ray is hitting the sphere at the moment. Then you’ll have to calculate the way the sphere should rotate, in order for the original point of contact to move to the new point of contact.

I think the following script should work:

Edit: Changed it so that the camera moves and not rotates.

public class SphereRotation : MonoBehaviour
{
	public Camera rotatingCamera;
	bool hasGrabbedPoint = false;
	Vector3 grabbedPoint;
 
	void Update()
	{
		if (Input.GetMouseButton(0))
		{
			if (!hasGrabbedPoint)
			{
				hasGrabbedPoint = true;
				grabbedPoint = getTouchedPoint();
			}
			else
			{
				Vector3 targetPoint = getTouchedPoint();
				Quaternion rot = Quaternion.FromToRotation(grabbedPoint, targetPoint);
				
				// you need to rotate the camera around the center of the sphere, the opposite of rot		
				Vector3 toCamera = rotatingCamera.transform.localPosition;
				toCamera = rot.Inverse() * toCamera;
				rotatingCamera.transform.localPosition = toCamera;
				
				// make camera look at center of sphere
				rotatingCamera.transform.LookAt(transform.position);
			}
		}
		else
			hasGrabbedPoint = false;
	}
 
	Vector3 getTouchedPoint()
	{
		RaycastHit hit;
		Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit);
 
		return transform.InverseTransformPoint(hit.point);
	}
}