Unity摄像机控制:
视野缩放:通过向前滚动鼠标滑轮可拉近视野,向后滚动鼠标滑轮可拉远视野。
视野移动:按住鼠标左键不放时,移动鼠标可控制视野向鼠标图标移动方向平滑移动,即视野可在上、下、左、右四个方向上平移。
视野旋转:按住鼠标右键不放时,移动鼠标可控制视野向鼠标图标移动方向旋转。垂直方向旋转范围为-90度到90度,水平方向无限制,可360度旋转。
视野跳跃:双击鼠标左键可控制视野向鼠标图标方向跳跃一段距离;双击鼠标右键可控制视野向后跳跃一段距离。
///文件名:CameraController.cs
///功能:摄像机自由控制类///摘要:
///创建日期:2016.1.13
///修改日志:
using UnityEngine;
public class CameraController : MonoBehaviour
{
private static Transform cameraSelf;
public float scrollSpeed;
public float moveSpeed;
public float rotateSpeed = 2;
public float moveSpeedMin = 0.5f;
public float moveSpeedMax = 500f;
public float scrollSpeedMax = 30000;
public float scrollSpeedMin = 50f;
public float heightMax = 15000f;
public float heightMin = 20f;
public float cameraXMin = 2000f;
public float cameraXMax = 18000f;
public float cameraZMin = 3000f;
public float cameraZMax = 27000f;
public float jumpHeightMin;
public float jumpSpeedMax;
public float jumpSpeedMin;
private float jumpDistance;
private float mouseDownDuration = 0.3f;
private float lastLeftDownTime = -1;
private float lastrightDownTime = -1;
private float rotate_X;
private float rotate_Y;
private float move_X;
private float move_Y;
Ray ray;
RaycastHit hitInfo;
void Start()
{
cameraSelf = transform;
}
void LateUpdate()
{
CameraJump();
CameraZoom();
CameraRotate();
CameraMove();
CameraLimit();
}
/// <summary>
/// 滑轮控制视野缩放
/// </summary>
void CameraZoom()
{
float scrollAxis = Input.GetAxis("Mouse ScrollWheel");
if (scrollAxis != 0)
{
scrollSpeed = (scrollSpeedMin + (cameraSelf.position.y - heightMin)
/ (heightMax - heightMin) * (scrollSpeedMax - scrollSpeedMin));
scrollSpeed = Mathf.Clamp(scrollSpeed, scrollSpeedMin, scrollSpeedMax);
Vector3 targetPoint = cameraSelf.position + cameraSelf.forward
* scrollAxis * scrollSpeed;
cameraSelf.position = Vector3.Lerp(cameraSelf.position, targetPoint, Time.deltaTime);
}
}
/// <summary>
/// 鼠标左键控制移动
/// </summary>
void CameraMove()
{
if (Input.GetMouseButton(0))
{
moveSpeed = moveSpeedMin + (cameraSelf.position.y - heightMin)
/ (heightMax - heightMin) * (moveSpeedMax - moveSpeedMin);
moveSpeed = Mathf.Clamp(moveSpeed, moveSpeedMin, moveSpeedMax);
move_Y = Input.GetAxis("Mouse Y") * moveSpeed;
move_X = Input.GetAxis("Mouse X") * moveSpeed;
cameraSelf.position += -cameraSelf.right * move_X - cameraSelf.up * move_Y;
}
}
/// <summary>
/// 鼠标右键控制旋转
/// </summary>
void CameraRotate()
{
if (Input.GetMouseButton(1))
{
rotate_X = cameraSelf.eulerAngles.x;
rotate_Y = cameraSelf.eulerAngles.y;
rotate_X -= Input.GetAxis("Mouse Y") * rotateSpeed;
rotate_Y += Input.GetAxis("Mouse X") * rotateSpeed;
rotate_X = ClampAngle(rotate_X, 1, 89);
rotate_Y = ClampAngle(rotate_Y, -360, 360);
cameraSelf.rotation = Quaternion.Euler(rotate_X, rotate_Y, 0);
}
}
/// <summary>
/// 规划角度
/// </summary>
/// <param name="angle">实际角度</param>
/// <param name="minAngle">最小角度</param>
/// <param name="maxAgnle">最大角度</param>
/// <returns>限制范围内的角度</returns>
float ClampAngle(float angle, float minAngle, float maxAgnle)
{
if (angle <= -360)
angle += 360;
if (angle >= 360)
angle -= 360;
return Mathf.Clamp(angle, minAngle, maxAgnle);
}
///视野跳跃
void CameraJump()
{
//双左键击视野向鼠标点击方向跳跃
if (Input.GetMouseButtonDown(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Physics.Raycast(ray, out hitInfo);
if (Time.time - lastLeftDownTime < mouseDownDuration)
{
jumpDistance = (jumpSpeedMin + (cameraSelf.position.y - jumpHeightMin) /
(heightMax - jumpHeightMin) * (jumpSpeedMax - jumpSpeedMin));
cameraSelf.position += ray.direction * jumpDistance;
}
lastLeftDownTime = Time.time;
}
//双击右键视野向后退
if (Input.GetMouseButtonDown(1))
{
if (Time.time - lastrightDownTime < mouseDownDuration)
{
jumpDistance = (jumpSpeedMin + (cameraSelf.position.y - jumpHeightMin) /
(heightMax - jumpHeightMin) * (jumpSpeedMax - jumpSpeedMin));
cameraSelf.position -= cameraSelf.forward * jumpDistance;
}
lastrightDownTime = Time.time;
}
}
/// <summary>
/// 摄像限制
/// </summary>
void CameraLimit()
{
Vector3 vec = cameraSelf.position;
vec.x = Mathf.Clamp(vec.x, cameraXMin, cameraXMax);
vec.y = Mathf.Clamp(vec.y, heightMin, heightMax);
vec.z = Mathf.Clamp(vec.z, cameraZMin, cameraZMax);
cameraSelf.position = vec;
}
}
在实际使用过程中可能需要实现在点击在界面UI上时不改变视野,这时可使用EventSystem.current.IsPointerOverGameObject(),通过此函数可判断是否点击到UI上,若点击到UI上则返回true,未点击到UI上则返回false。