Skip to content

Instantly share code, notes, and snippets.

@hiroshi-nishiura
Last active September 23, 2022 19:27
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 hiroshi-nishiura/f70838083ad818d38911bfb77beb7557 to your computer and use it in GitHub Desktop.
Save hiroshi-nishiura/f70838083ad818d38911bfb77beb7557 to your computer and use it in GitHub Desktop.
Orbit Camera Controller for Unity
using UnityEngine;
using UnityEditor;
#if UNITY_EDITOR
[RequireComponent(typeof(Camera))]
public class OrbitCameraController : MonoBehaviour
{
public bool _alignWithViewAtStart = true;
public bool _alignSceneViewAtQuit = false;
public bool _enableBallControl = false;
public bool _enableRollControl = false;
private Vector3 _pivot;
private Camera _camera;
private const float _translateCoef = 0.02f;
private const float _rotateCoef = 4.0f;
private const float _zoomCoef = 0.1f;
private const float _rollCoef = 2.0f;
void OnEnable()
{
_camera = GetComponent<Camera>();
if (_alignWithViewAtStart && _camera.targetDisplay == Display.activeEditorGameViewTarget)
{
SceneView sv = SceneView.lastActiveSceneView;
_pivot = sv.pivot;
transform.rotation = sv.rotation;
transform.position = _pivot - transform.forward * sv.cameraDistance;
}
}
void OnDisable()
{
if (_alignSceneViewAtQuit && _camera.targetDisplay == Display.activeEditorGameViewTarget)
{
SceneView sv = SceneView.lastActiveSceneView;
sv.pivot = _pivot;
sv.rotation = transform.rotation;
sv.size = Vector3.Distance(_pivot, transform.position) * Mathf.Sin(sv.cameraSettings.fieldOfView * 0.5f * Mathf.Deg2Rad);
}
}
void LateUpdate()
{
if(_camera.targetDisplay != Display.activeEditorGameViewTarget) return;
if (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt))
{
if (Input.GetMouseButton(0))
if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) Translate();
else RotateAroundPivot();
else if (Input.GetMouseButton(2)) Translate();
else if (Input.GetMouseButton(1))
if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl))
if (_enableRollControl) Roll();
else RotateAroundOrigin();
else Zoom();
transform.position += transform.forward * Input.mouseScrollDelta.y;
}
}
void Translate()
{
float coef = Vector3.Distance(_pivot, transform.position) * Mathf.Atan(_camera.fieldOfView * 0.5f) * _translateCoef;
if(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.LeftShift)) coef *= 2.0f;
Vector3 move = coef * (transform.right * Input.GetAxis("Mouse X") + transform.up * Input.GetAxis("Mouse Y"));
_pivot -= move;
transform.position -= move;
}
void RotateAroundPivot()
{
float coef = _rotateCoef;
if(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.LeftShift)) coef *= 2.0f;
transform.RotateAround(_pivot, _enableBallControl ? transform.up : Vector3.up, coef * Input.GetAxis("Mouse X"));
transform.RotateAround(_pivot, transform.right, coef * -Input.GetAxis("Mouse Y"));
}
void RotateAroundOrigin()
{
float coef = _rotateCoef;
if(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.LeftShift)) coef *= 2.0f;
transform.Rotate(coef * -Input.GetAxis("Mouse Y"), coef * Input.GetAxis("Mouse X"), 0);
}
void Zoom()
{
float coef = _zoomCoef * Vector3.Distance(_pivot, transform.position);
if(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.LeftShift)) coef *= 2.0f;
transform.position += coef * transform.forward * Input.GetAxis("Mouse X");
transform.position -= coef * transform.forward * Input.GetAxis("Mouse Y");
}
void Roll()
{
transform.Rotate(Vector3.forward, _rollCoef * Input.GetAxis("Mouse X"));
}
}
[CustomEditor(typeof(OrbitCameraController))]
public class OrbitCameraControllerEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if(GUILayout.Button("Reset Scene View"))
{
SceneView sv = SceneView.lastActiveSceneView;
sv.ResetCameraSettings();
sv.pivot = Vector3.zero;
sv.rotation = Quaternion.LookRotation(new Vector3(-1, -.7f, -1));
sv.size = 10f;
}
EditorGUILayout.LabelField("Alt Left : Orbit Around Pivot");
EditorGUILayout.LabelField("Alt Left Ctrl : Translate");
EditorGUILayout.LabelField("Alt Middle : Translate");
EditorGUILayout.LabelField("Alt Right or Wheel : Zoom");
EditorGUILayout.LabelField("Alt Right Ctrl : Roll or Rotate");
EditorGUILayout.LabelField("Shift : x2");
EditorGUILayout.HelpBox("To feedback, Copy Component of the Transform on runtime then Paste Component Values after quit.", MessageType.None);
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment