Skip to content

Instantly share code, notes, and snippets.

@alexpana
Last active January 15, 2017 08:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexpana/60cd295a8f6d4fc02afdbd763d43f598 to your computer and use it in GitHub Desktop.
Save alexpana/60cd295a8f6d4fc02afdbd763d43f598 to your computer and use it in GitHub Desktop.
using UnityEngine;
namespace Camera
{
public class OrbitCameraController : MonoBehaviour
{
private const float MIN_DISTANCE = 0.5f;
private const float MAX_DISTANCE = 50f;
private const float ZOOM_STEP = 1;
public Transform Target;
[Range (MIN_DISTANCE, MAX_DISTANCE)]
public float Distance;
public bool Turntable = false;
public float TurntableSpeed = 1.0f;
private bool _isControlled;
private SphericalCoordinates _sphericalCoordinates = new SphericalCoordinates (Vector3.zero);
private void Update ()
{
if (Target == null) {
return;
}
_isControlled = Input.GetMouseButton (1);
_sphericalCoordinates = new SphericalCoordinates (transform.position - Target.position) {
Radius = Mathf.Max (MIN_DISTANCE, Distance)
};
if (Turntable) {
_sphericalCoordinates.Azimuth += TurntableSpeed * Time.deltaTime;
}
// Prevent the camera from going above / under the target
_sphericalCoordinates.Inclination = Mathf.Clamp (_sphericalCoordinates.Inclination, 0.4f, Mathf.PI - 0.4f);
if (Input.GetMouseButtonDown (1)) {
Cursor.lockState = CursorLockMode.Locked;
}
if (Input.GetMouseButtonUp (1)) {
Cursor.lockState = CursorLockMode.None;
}
if (Input.GetAxis ("Mouse ScrollWheel") > 0) {
Distance = Mathf.Clamp (Distance - ZOOM_STEP, MIN_DISTANCE, MAX_DISTANCE);
}
if (Input.GetAxis ("Mouse ScrollWheel") < 0) {
Distance = Mathf.Clamp (Distance + ZOOM_STEP, MIN_DISTANCE, MAX_DISTANCE);
}
if (_isControlled) {
var deltaX = Input.GetAxis ("Mouse X");
var deltaY = Input.GetAxis ("Mouse Y");
_sphericalCoordinates.Azimuth -= deltaX * 0.1f;
_sphericalCoordinates.Inclination += deltaY * 0.1f;
}
transform.position = _sphericalCoordinates.ToVector3 () + Target.position;
transform.LookAt (Target);
}
}
internal class SphericalCoordinates
{
public float Radius;
public float Inclination;
public float Azimuth;
public SphericalCoordinates (Vector3 Object)
{
var radius = Mathf.Sqrt (Object.x * Object.x + Object.y * Object.y + Object.z * Object.z);
Radius = radius;
Inclination = Mathf.Acos (Object.y / radius);
Azimuth = Mathf.Atan2 (Object.z, Object.x);
}
public Vector3 ToVector3 ()
{
return new Vector3 (
Radius * Mathf.Sin (Inclination) * Mathf.Cos (Azimuth),
Radius * Mathf.Cos (Inclination),
Radius * Mathf.Sin (Inclination) * Mathf.Sin (Azimuth));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment