Last active
January 15, 2017 08:52
-
-
Save alexpana/60cd295a8f6d4fc02afdbd763d43f598 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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