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);
}
}