using UnityEngine;
using System.Collections;
using UnityEngine.AI;
public class FreeTPSCamera : MonoBehaviour
{
[Header("相机距离")]
public float freeDistance = 2;
// 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(1, 10, 10);
/// <summary>
/// Range limit of angle.
/// </summary>
public Range angleRange = new Range(5, 70);
/// <summary>
/// Range limit of distance.
/// </summary>
public Range distanceRange = new Range(1, 10);
/// <summary>
/// Damper for move and rotate.
/// </summary>
//[Range(0, 10)]
private float damper = 200;
/// <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 ||UNITY_STANDALONE_WIN
//AroundByMouseInput();
AroundByPCTouchInput();
#elif UNITY_ANDROID || UNITY_IPHONE
AroundByMobileInput();
#endif
}
//记录上一次手机触摸位置判断用户是在左放大还是缩小手势
private Vector2 oldPosition1;
private Vector2 oldPosition2;
private bool m_IsSingleFinger;
bool isDrag;
protected void AroundByPCTouchInput()
{
if (Input.touchCount == 1)
{
if (Input.touches[0].phase == TouchPhase.Began)
{
isDrag = false;
}
if (Input.touches[0].phase == TouchPhase.Moved)
{
isDrag = true;
targetAngles.y += Input.GetTouch(0).deltaPosition.x * mouseSettings.pointerSensitivity * Time.deltaTime;
targetAngles.x -= Input.GetTouch(0).deltaPosition.y * mouseSettings.pointerSensitivity * Time.deltaTime;
//Range.
targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max);
}
if (Input.touches[0].phase == TouchPhase.Ended)
{
//Debug.Log("isDrag = " + isDrag);
if (!isDrag)
{
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
MainEvent.UserClick(ray);
}
}
//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();
//备份上一次触摸点的位置,用于对比
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;
}
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") * Time.deltaTime * damper * 2;
targetAngles.x -= Input.GetAxis("Mouse Y") * Time.deltaTime * damper * 2;
//Range.
targetAngles.x = Mathf.Clamp(targetAngles.x, angleRange.min, angleRange.max);
}
//Mouse scrollwheel.
if (canScale)
{
targetDistance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * damper * 2;
}
// m_debugTip.text = Input.GetAxis("Mouse ScrollWheel").ToString() + " + " + targetDistance.ToString();
targetDistance = Mathf.Clamp(targetDistance, distanceRange.min, distanceRange.max);
//Lerp.
CurrentAngles = Vector2.Lerp(CurrentAngles, targetAngles, Time.deltaTime * damper);
CurrentDistance = Mathf.Lerp(CurrentDistance, targetDistance, Time.deltaTime * damper);
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;
}
public void SetCameraScale(bool bo)
{
canScale = bo;
}
#endregion
}