using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; /// /// [RequireComponent(typeof(Camera))] public class AroundCamera : MonoBehaviour { #region Field and Property /// /// Around center. /// public Transform target; /// /// Settings of mouse button, pointer and scrollwheel. /// public MouseSettings mouseSettings = new MouseSettings(1, 10, 10); /// /// Range limit of angle. /// public Range angleRange = new Range(-90, 90); /// /// Range limit of distance. /// public Range distanceRange = new Range(1, 10); /// /// Damper for move and rotate. /// [Range(0, 10)] public float damper = 5; /// /// Camera current angls. /// public Vector2 CurrentAngles { set; get; } /// /// Current distance from camera to target. /// public float CurrentDistance { set; get; } /// /// Camera target angls. /// public Vector2 targetAngles; /// /// Target distance from camera to target. /// public float targetDistance; public int mLayer; public bool mIsMovableDetection = true; public bool mRotateEnable = true; public static bool mIsTouchedUI = false; #endregion #region Protected Method protected virtual void Start() { Initialize(); } private void Update() { if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)) { if (EventSystem.current.IsPointerOverGameObject()) { mIsTouchedUI = true; } } if(Input.GetMouseButtonUp(0) || Input.GetMouseButtonUp(1)) { mIsTouchedUI = false; } } public static bool IsTouchedUI() { return mIsTouchedUI; } public float mCameraDistance = 0.0f; protected virtual void LateUpdate() { Ray ray = new Ray(Camera.main.transform.position, Camera.main.transform.forward); RaycastHit hit; if (Physics.Raycast(ray, out hit, float.MaxValue)) { float cameraDistance = Vector3.Distance(Camera.main.transform.position, hit.point); mouseSettings.wheelSensitivity = cameraDistance / 4; mCameraDistance = cameraDistance; } AroundByMouse(); } /// /// Initialize component. /// public virtual void Initialize() { CurrentAngles = targetAngles = transform.eulerAngles; CurrentDistance = targetDistance = Vector3.Distance(transform.position, target.position); } /// /// Camera around target by mouse. /// public void AroundByMouse() { if (IsTouchedUI()) return; float preDistance = targetDistance; Vector2 preAngle = targetAngles; bool mouseOperate = false; #if !UNITY_ANDROID if (Input.GetMouseButton(mouseSettings.mouseButtonID) && !IsTouchedUI()) { //Mouse pointer. targetAngles.y += Input.GetAxis("Mouse X") * mouseSettings.pointerSensitivity; targetAngles.x -= Input.GetAxis("Mouse Y") * mouseSettings.pointerSensitivity; //Range. targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max); mouseOperate = true; } if (Input.GetAxis("Mouse ScrollWheel") != 0f) { //Mouse scrollwheel. targetDistance -= Input.GetAxis("Mouse ScrollWheel") * mouseSettings.wheelSensitivity; targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max); mouseOperate = true; } #else if (Input.touchCount == 2) { Touch touch0 = Input.GetTouch(0); Touch touch1 = Input.GetTouch(1); if (touch0.phase == TouchPhase.Moved && touch1.phase == TouchPhase.Moved) { Vector2 lastDelta = (touch0.position - touch0.deltaPosition) - (touch1.position - touch1.deltaPosition); Vector2 currDelta = touch0.position - touch1.position; float deltaMagnitude = currDelta.magnitude - lastDelta.magnitude; targetDistance -= deltaMagnitude * mouseSettings.wheelSensitivity * 0.02f; targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max); CurrentDistance = targetDistance; mouseOperate = true; } } if (Input.touchCount == 1 && mRotateEnable) { //Mouse pointer. targetAngles.y += Input.GetAxis("Mouse X") * mouseSettings.pointerSensitivity * 0.2f; ; targetAngles.x -= Input.GetAxis("Mouse Y") * mouseSettings.pointerSensitivity * 0.2f; ; //Range. targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max); CurrentAngles = targetAngles; mouseOperate = true; } #endif if (mouseOperate && !MovableDetection()) { targetDistance = preDistance; targetAngles = preAngle; return; } #if !UNITY_ANDROID //Lerp. CurrentAngles = Vector2.Lerp(CurrentAngles, targetAngles, damper * Time.deltaTime); CurrentDistance = Mathf.Lerp(CurrentDistance, targetDistance, damper * Time.deltaTime); //Not Lerp //CurrentAngles = targetAngles; //CurrentDistance = targetDistance; #endif //Update transform position and rotation. transform.rotation = Quaternion.Euler(CurrentAngles); transform.position = target.position - transform.forward * CurrentDistance; #region #if !UNITY_ANDROID if (Vector2.Distance(CurrentAngles, targetAngles) > 1.0f) PlayerPrefs.SetInt("CameraRotating", 1); else PlayerPrefs.SetInt("CameraRotating", 0); if (Mathf.Abs(CurrentDistance - targetDistance) > 1.0f) PlayerPrefs.SetInt("CameraZooming", 1); else PlayerPrefs.SetInt("CameraZooming", 0); #endif #endregion } public bool MovableDetection() { if (!mIsMovableDetection) return true; Quaternion preRot = transform.rotation; Vector3 prePos = transform.position; transform.rotation = Quaternion.Euler(targetAngles); transform.position = target.position - transform.forward * targetDistance; if (Physics.Linecast(prePos, transform.position)) { transform.rotation = preRot; transform.position = prePos; return false; } return true; } #endregion }