using UnityEngine;using System;using System.Collections; public class CameraController : MonoBehaviour { // Text m_debugTip; public bool canRotation_X = true; public bool canRotation_Y = true; public bool canScale = true; #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(0, 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 { protected set; get; } /// <summary> /// Current distance from camera to target. /// </summary> public float CurrentDistance { protected set; get; } /// <summary> /// Camera target angls. /// </summary> protected Vector2 targetAngles; /// <summary> /// Target distance from camera to target. /// </summary> protected float targetDistance; #endregion #region Protected Method protected virtual void Start() { // m_debugTip = GameObject.Find("Text").GetComponent<Text>(); CurrentAngles = targetAngles = transform.eulerAngles; CurrentDistance = targetDistance = Vector3.Distance(transform.position, target.position); } protected virtual void LateUpdate() {#if UNITY_EDITOR AroundByMouseInput();#elif UNITY_ANDROID || UNITY_IPHONE AroundByMobileInput();#endif } //记录上一次手机触摸位置判断用户是在左放大还是缩小手势 private Vector2 oldPosition1; private Vector2 oldPosition2; private bool m_IsSingleFinger; /* private void ScaleCamera() { //计算出当前两点触摸点的位置 var tempPosition1 = Input.GetTouch(0).position; var tempPosition2 = Input.GetTouch(1).position; float currentTouchDistance = Vector3.Distance(tempPosition1, tempPosition2); float lastTouchDistance = Vector3.Distance(oldPosition1, oldPosition2); //计算上次和这次双指触摸之间的距离差距 //然后去更改摄像机的距离 distance -= ( currentTouchDistance - lastTouchDistance ) * scaleFactor * Time.deltaTime; //把距离限制住在min和max之间 distance = Mathf.Clamp(distance, minDistance, maxDistance); //备份上一次触摸点的位置,用于对比 oldPosition1 = tempPosition1; oldPosition2 = tempPosition2; } */ protected void AroundByMobileInput() { if (Input.touchCount == 1) { if (Input.touches[0].phase == TouchPhase.Moved) { 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); } //Mouse pointer. m_IsSingleFinger = true; } //Mouse scrollwheel. if (canScale) { if (Input.touchCount > 1) { //计算出当前两点触摸点的位置 if (m_IsSingleFinger) { oldPosition1 = Input.GetTouch(0).position; oldPosition2 = Input.GetTouch(1).position; } if (Input.touches[0].phase == TouchPhase.Moved && Input.touches[1].phase == TouchPhase.Moved) { var tempPosition1 = Input.GetTouch(0).position; var tempPosition2 = Input.GetTouch(1).position; float currentTouchDistance = Vector3.Distance(tempPosition1, tempPosition2); float lastTouchDistance = Vector3.Distance(oldPosition1, oldPosition2); //计算上次和这次双指触摸之间的距离差距 //然后去更改摄像机的距离 targetDistance -= ( currentTouchDistance - lastTouchDistance ) * Time.deltaTime * mouseSettings.wheelSensitivity; // m_debugTip.text = ( currentTouchDistance - lastTouchDistance ).ToString() + " + " + targetDistance.ToString(); //把距离限制住在min和max之间 //备份上一次触摸点的位置,用于对比 oldPosition1 = tempPosition1; oldPosition2 = tempPosition2; m_IsSingleFinger = false; } } } targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max); //Lerp. CurrentAngles = Vector2.Lerp(CurrentAngles, targetAngles, damper * Time.deltaTime); CurrentDistance = Mathf.Lerp(CurrentDistance, targetDistance, damper * Time.deltaTime); if (!canRotation_X) targetAngles.y = 0; if (!canRotation_Y) targetAngles.x = 0; //Update transform position and rotation. transform.rotation = Quaternion.Euler(CurrentAngles); transform.position = target.position - transform.forward * CurrentDistance; // transform.position = target.position - Vector3.forward * CurrentDistance; } /// <summary> /// Camera around target by mouse input. /// </summary> protected void AroundByMouseInput() { if (Input.GetMouseButton(mouseSettings.mouseButtonID)) { //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); } //Mouse scrollwheel. if (canScale) { targetDistance -= Input.GetAxis("Mouse ScrollWheel") * mouseSettings.wheelSensitivity; } // m_debugTip.text = Input.GetAxis("Mouse ScrollWheel").ToString() + " + " + targetDistance.ToString(); targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max); //Lerp. CurrentAngles = Vector2.Lerp(CurrentAngles, targetAngles, damper * Time.deltaTime); CurrentDistance = Mathf.Lerp(CurrentDistance, targetDistance, damper * Time.deltaTime); if (!canRotation_X) targetAngles.y = 0; if (!canRotation_Y) targetAngles.x = 0; //Update transform position and rotation. transform.rotation = Quaternion.Euler(CurrentAngles); transform.position = target.position - transform.forward * CurrentDistance; // transform.position = target.position - Vector3.forward * CurrentDistance; } #endregion} [Serializable]public struct MouseSettings{ /// <summary> /// ID of mouse button. /// </summary> public int mouseButtonID; /// <summary> /// Sensitivity of mouse pointer. /// </summary> public float pointerSensitivity; /// <summary> /// Sensitivity of mouse ScrollWheel. /// </summary> public float wheelSensitivity; /// <summary> /// Constructor. /// </summary> /// <param name="mouseButtonID">ID of mouse button.</param> /// <param name="pointerSensitivity">Sensitivity of mouse pointer.</param> /// <param name="wheelSensitivity">Sensitivity of mouse ScrollWheel.</param> public MouseSettings(int mouseButtonID, float pointerSensitivity, float wheelSensitivity) { this.mouseButtonID = mouseButtonID; this.pointerSensitivity = pointerSensitivity; this.wheelSensitivity = wheelSensitivity; }} /// <summary>/// Range form min to max./// </summary>[Serializable]public struct Range{ /// <summary> /// Min value of range. /// </summary> public float min; /// <summary> /// Max value of range. /// </summary> public float max; /// <summary> /// Constructor. /// </summary> /// <param name="min">Min value of range.</param> /// <param name="max">Max value of range.</param> public Range(float min, float max) { this.min = min; this.max = max; }} /// <summary>/// Rectangle area on plane./// </summary>[Serializable]public struct PlaneArea{ /// <summary> /// Center of area. /// </summary> public Transform center; /// <summary> /// Width of area. /// </summary> public float width; /// <summary> /// Length of area. /// </summary> public float length; /// <summary> /// Constructor. /// </summary> /// <param name="center">Center of area.</param> /// <param name="width">Width of area.</param> /// <param name="length">Length of area.</param> public PlaneArea(Transform center, float width, float length) { this.center = center; this.width = width; this.length = length; }} /// <summary>/// Target of camera align./// </summary>[Serializable]public struct AlignTarget{ /// <summary> /// Center of align target. /// </summary> public Transform center; /// <summary> /// Angles of align. /// </summary> public Vector2 angles; /// <summary> /// Distance from camera to target center. /// </summary> public float distance; /// <summary> /// Range limit of angle. /// </summary> public Range angleRange; /// <summary> /// Range limit of distance. /// </summary> public Range distanceRange; /// <summary> /// Constructor. /// </summary> /// <param name="center">Center of align target.</param> /// <param name="angles">Angles of align.</param> /// <param name="distance">Distance from camera to target center.</param> /// <param name="angleRange">Range limit of angle.</param> /// <param name="distanceRange">Range limit of distance.</param> public AlignTarget(Transform center, Vector2 angles, float distance, Range angleRange, Range distanceRange) { this.center = center; this.angles = angles; this.distance = distance; this.angleRange = angleRange; this.distanceRange = distanceRange; }}