using UnityEngine;
using System.Collections;
public class SimpleFreeCamera : MonoBehaviour
{
private Transform CameraTr;
public Transform ParentTr;
private Camera Camera;
//Y軸最大旋轉角度
public float MaxY = 90f;
public float MinY = 0f;
//縮放變量;
public float distance = 10f;
public float MinDistance = 2f;
public float MaxDistance = 100f;
public float speed = 5f;
//地面平面
private Plane defaultPlane;
//移動變量;
private Vector3 m_mouseMovePos = Vector3.zero;
private Vector3 LastViewTargetPoint;
private bool IsMove = false;
void Awake()
{
Camera = GetComponent<Camera>();
CameraTr = this.transform;
ParentTr = ParentTr==null?new GameObject("SimpleFreeCamera").transform: ParentTr;
CameraTr.SetParent(ParentTr);
transform.LookAt(ParentTr);
Init();
}
void Init()
{
CameraTr.transform.localPosition = new Vector3(0, 0, -distance);
CameraTr.transform.localRotation = Quaternion.identity;
}
void Update()
{
if (Input.GetMouseButton(1))//鼠標右鍵旋轉
{
Rotate(Input.GetAxis("Mouse Y"), Input.GetAxis("Mouse X"));
LastViewTargetPoint = ParentTr.localPosition;
SetPanle(LastViewTargetPoint);
}
if (Input.GetAxis("Mouse ScrollWheel") != 0) //鼠標中鍵滾輪場景縮放;
{
Scale(Input.GetAxis("Mouse ScrollWheel"));
LastViewTargetPoint = ParentTr.localPosition;
SetPanle(LastViewTargetPoint);
}
//按住鼠標中鍵場景移動;
if (Input.GetMouseButtonDown(2))//按下鼠標中鍵 記錄移動起點 開啓移動操作
{
IsMove = true;
LastViewTargetPoint = ParentTr.localPosition;
SetPanle(LastViewTargetPoint);
m_mouseMovePos = GetMouse3DPosition();
}
else if (Input.GetMouseButton(2)) //按住鼠標中鍵 根據位移移動
{
if (IsMove)
{
ParentTr.localPosition = Vector3.Lerp(ParentTr.localPosition, LastViewTargetPoint - GetMouse3DPosition() + m_mouseMovePos, 0.5f);
LastViewTargetPoint = ParentTr.localPosition;
}
}
else if (Input.GetMouseButtonUp(2))//放開鼠標中鍵 結束移動操作
{
IsMove = false;
SetPanle(LastViewTargetPoint);
}
}
private Vector3 GetMouse3DPosition()
{
Ray ray = Camera.ScreenPointToRay(Input.mousePosition);
float enter;
defaultPlane.Raycast(ray, out enter);
return ray.GetPoint(enter);
}
/// <summary>
/// 旋轉目標
/// </summary>
/// <param name="dy"></param>
/// <param name="dx"></param>
private void Rotate(float dy, float dx)
{
float deltX = ParentTr.localRotation.eulerAngles.y;
float deltY = ParentTr.localRotation.eulerAngles.x;
deltX += dx * speed;
deltY -= dy * speed;
deltX = ClampAngle(deltX, -360, 360);
deltY = ClampAngle(deltY, MinY, MaxY);
ParentTr.rotation = Quaternion.Euler(deltY, deltX, 0);
}
private void Scale(float s)
{
if (Mathf.Abs(transform.localPosition.z) < MinDistance)
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, -MinDistance);
if (Mathf.Abs(transform.localPosition.z) > MaxDistance)
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, -MaxDistance);
float deltD = s * 10f;
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, transform.localPosition.z + deltD);
}
private float ClampAngle(float angle, float minAngle, float maxAgnle)
{
if (angle <= -360)
angle += 360;
if (angle >= 360)
angle -= 360;
return Mathf.Clamp(angle, minAngle, maxAgnle);
}
/// <summary>
/// 設置平面
/// </summary>
/// <param name="_v3"></param>
private void SetPanle(Vector3 _v3)
{
defaultPlane.SetNormalAndPosition(-transform.forward, _v3);
}
}