123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
-
- using UnityEngine;
- using UnityEngine.EventSystems;
- using UnityEngine.UI;
- /// <summary>
- /// </summary> [RequireComponent(typeof(Camera))]
- public class AroundCamera : MonoBehaviour
- {
- #region Field and Property
- /// <summary>
- /// Around center.
- /// </summary>
- public Transform target;
- /// <summary>
- /// Settings of mouse button, pointer and scrollwheel.
- /// </summary>
- public MouseSettings mouseSettings = new MouseSettings(1, 10, 10);
- /// <summary>
- /// Range limit of angle.
- /// </summary>
- public Range angleRange = new Range(-90, 90);
- /// <summary>
- /// Range limit of distance.
- /// </summary>
- public Range distanceRange = new Range(1, 10);
- /// <summary>
- /// Damper for move and rotate.
- /// </summary>
- [Range(0, 10)]
- public float damper = 5;
- /// <summary>
- /// Camera current angls.
- /// </summary>
- public Vector2 CurrentAngles { set; get; }
- /// <summary>
- /// Current distance from camera to target.
- /// </summary>
- public float CurrentDistance { set; get; }
- /// <summary>
- /// Camera target angls.
- /// </summary>
- public Vector2 targetAngles;
- /// <summary>
- /// Target distance from camera to target.
- /// </summary>
- 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();
- }
- /// <summary>
- /// Initialize component.
- /// </summary>
- public virtual void Initialize()
- {
- CurrentAngles = targetAngles = transform.eulerAngles;
- CurrentDistance = targetDistance = Vector3.Distance(transform.position, target.position);
- }
- /// <summary>
- /// Camera around target by mouse.
- /// </summary>
- 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
- }
|