From c331f1029c6e64b693882562fb1c66fca37483fc Mon Sep 17 00:00:00 2001 From: Adam Mitchell <41760870+AdamMitchell-ms@users.noreply.github.com> Date: Fri, 3 May 2019 16:57:27 -0700 Subject: [PATCH] OrbitCamera now supports right mouse buttons to change position (#422) * right mouse camera controls * More accurate right click mouse motion --- Examples/OrbitCameraController.cs | 76 ++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/Examples/OrbitCameraController.cs b/Examples/OrbitCameraController.cs index 071071fe7..a3d678389 100644 --- a/Examples/OrbitCameraController.cs +++ b/Examples/OrbitCameraController.cs @@ -3,10 +3,11 @@ // Taken from http://wiki.unity3d.com/index.php?title=MouseOrbitImproved namespace UnityGLTF.Examples { + [RequireComponent(typeof(Camera))] [AddComponentMenu("Camera-Control/Mouse Orbit with zoom")] public class OrbitCameraController : MonoBehaviour { - public Transform target; + public Vector3 targetPosition = Vector3.zero; public float distance = 5.0f; public float xSpeed = 120.0f; public float ySpeed = 120.0f; @@ -18,21 +19,28 @@ public class OrbitCameraController : MonoBehaviour public float distanceMin = .5f; public float distanceMax = 150f; + private Camera camera; + private Rigidbody cameraRigidBody; - float x = 0.0f; - float y = 0.0f; + private float x = 0.0f; + private float y = 0.0f; + private Vector3 prevMousePosition; Quaternion rotation; // Use this for initialization void Start() { + camera = GetComponent(); + Vector3 angles = transform.eulerAngles; x = angles.y; y = angles.x; rotation = Quaternion.Euler(y, x, 0); + prevMousePosition = Input.mousePosition; + cameraRigidBody = GetComponent(); // Make the rigid body not change rotation @@ -44,38 +52,52 @@ void Start() void LateUpdate() { - if (target) + var height = Display.main.renderingHeight; + var width = Display.main.renderingWidth; + + if (Input.GetMouseButton(0)) { - if (Input.GetMouseButton(0)) - { - x += Input.GetAxis("Mouse X") * xSpeed * 0.06f; - y -= Input.GetAxis("Mouse Y") * ySpeed * 0.06f; + x += Input.GetAxis("Mouse X") * xSpeed * 0.06f; + y -= Input.GetAxis("Mouse Y") * ySpeed * 0.06f; - y = ClampAngle(y, yMinLimit, yMaxLimit); + y = ClampAngle(y, yMinLimit, yMaxLimit); - rotation = Quaternion.Euler(y, x, 0); - } + rotation = Quaternion.Euler(y, x, 0); + } + else if (Input.GetMouseButton(1)) + { + var prevMouseWorldPosition = ProjectScreenPointToTargetPlane(prevMousePosition); + var mouseWorldPosition = ProjectScreenPointToTargetPlane(Input.mousePosition); - var height = Display.main.renderingHeight; - var width = Display.main.renderingWidth; + targetPosition += prevMouseWorldPosition - mouseWorldPosition; + } - var mouseOverRenderArea = - Input.mousePosition.x >= 0 && - Input.mousePosition.x <= width && - Input.mousePosition.y >= 0 && - Input.mousePosition.y <= height; + var mouseOverRenderArea = + Input.mousePosition.x >= 0 && + Input.mousePosition.x <= width && + Input.mousePosition.y >= 0 && + Input.mousePosition.y <= height; - if (Input.GetMouseButton(0) || mouseOverRenderArea) - { - distance = Mathf.Clamp(distance * Mathf.Exp(-Input.GetAxis("Mouse ScrollWheel") * zoomSpeed), distanceMin, distanceMax); - } + if (Input.GetMouseButton(0) || mouseOverRenderArea) + { + distance = Mathf.Clamp(distance * Mathf.Exp(-Input.GetAxis("Mouse ScrollWheel") * zoomSpeed), distanceMin, distanceMax); + } - Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance); - Vector3 position = rotation * negDistance + target.position; + Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance); + Vector3 position = rotation * negDistance + targetPosition; - transform.rotation = rotation; - transform.position = position; - } + transform.rotation = rotation; + transform.position = position; + + prevMousePosition = Input.mousePosition; + } + + private Vector3 ProjectScreenPointToTargetPlane(Vector3 screenPosition) + { + var ray = camera.ScreenPointToRay(screenPosition); + var planeDistance = distance / Mathf.Cos(Mathf.Deg2Rad * Vector3.Angle(camera.transform.forward, ray.direction)); + + return camera.transform.position + (ray.direction * planeDistance); } public static float ClampAngle(float angle, float min, float max)