该脚本适用于大场景浏览时摄像机位移的脚本,可以控制摄像机的移动范围,和俯仰角,避免出现旋转360度,镜头中出现倒着看的情况。
该脚本的核心代码是通过update函数,获取相机每一帧的旋转角度和位置,然后再判断位置 和俯仰角, 如果超出界限,则将值归回每一帧初的旋转角度和位置,达到限制相机位移和角度。代码思路来源网友,自己将代码封装,供大家参考,其中有一个问题还没有解决,即判断倾斜,然后归正。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamerraMove : MonoBehaviour
{
//x轴 最大值、最小值
[Header("X轴范围")]
public float xMaxMove = 50;
public float xMinMove = -385;
//y轴 最大值、最小值
[Header("Y轴范围")]
public float yMaxMove = 58;
public float yMinMove = 1;
//z轴 最大值、最小值
[Header("Z轴范围")]
public float zMaxMove = 180;
public float zMinMove = -157;
[Header("俯仰角范围")]
public float xMaxAngle;
public float xMinAngle;
[Header("灵敏度")]
public float MoveSensitivity;
public float AngleSensitivity;
#region 基础定义
Transform CammeraMain;
//滑轮滚动基数
float WheelMove = 0;
//鼠标每帧移动基数
float MouseMove_X = 0;
float MouseMove_Y = 0;
//相机自身X/Y轴方向
Vector3 X_Aix = new Vector3(1, 0, 0);
Vector3 Y_Aix = new Vector3(0, 1, 0);
//相机x轴在水平面投影
Vector3 HX_Aix = new Vector3(1, 0, 0);
//世界坐标Y轴
Vector3 WY_Aix = new Vector3(0, 1, 0);
private Vector3 LPosition;//控制点
private float LRotation_X;//俯仰角控制点
#endregion
// Use this for initialization
void Start()
{
CammeraMain = transform;
}
// Update is called once per frame
void Update()
{
//更新相机自身X/Y轴方向
X_Aix = CammeraMain.right;
Y_Aix = CammeraMain.up;
//获取每一帧物体的位置 和俯仰角
LPosition = transform.position;
LRotation_X = transform.localEulerAngles.x;
#region 鼠标右击相机旋转
if (Input.GetMouseButton(1))
{
if ((MouseMove_X = Input.GetAxis("Mouse X")) != 0)
{
HX_Aix.x = X_Aix.x;
HX_Aix.z = X_Aix.z;
CammeraMain.Rotate(WY_Aix, MouseMove_X* AngleSensitivity, Space.World);
}
if ((MouseMove_Y = Input.GetAxis("Mouse Y")) != 0)
{
CammeraMain.Rotate(X_Aix, -MouseMove_Y* AngleSensitivity, Space.World);
}
}
#endregion
#region 鼠标滑动滚轮移动
//滑轮滚动 摄像机前后移动
if ((WheelMove = Input.GetAxis("Mouse ScrollWheel")) != 0)
{
CammeraMain.Translate(0, 0, WheelMove* MoveSensitivity);
}
//摄像机在世界坐标下的水平移动
if (Input.GetMouseButton(2))
{
CammeraMain.Translate(Vector3.right * MoveSensitivity * Time.deltaTime * -Input.GetAxis("Mouse X"));
//纵向平移,若相机垂直地面则向前平移
CammeraMain.Translate(Vector3.up * MoveSensitivity * Time.deltaTime * -Input.GetAxis("Mouse Y"));
}
#endregion
#region 控制摄像机位移
if ((transform.position.x > xMaxMove || transform.position.x < xMinMove))
{
transform.position = new Vector3(LPosition.x, transform.position.y, transform.position.z);
}
//检查相机y轴
if ((transform.position.y > yMaxMove || transform.position.y < yMinMove))
{
transform.position = new Vector3(transform.position.x, LPosition.y, transform.position.z);
}
//检查相机z轴
if ((transform.position.z > zMaxMove || transform.position.z < zMinMove))
{
transform.position = new Vector3(transform.position.x, transform.position.y, LPosition.z);
}
#endregion
#region 控制摄像机俯仰角
if (CheckAngle(transform.localEulerAngles.x) > xMaxAngle || CheckAngle(transform.localEulerAngles.x) < xMinAngle) {
transform.localEulerAngles = new Vector3(LRotation_X, transform.localEulerAngles.y, transform.localEulerAngles.z);
}
#endregion
}
private float CheckAngle(float value) // 将大于180度角进行以负数形式输出
{
float angle = value - 180;
if (angle > 0)
{
return angle - 180;
}
if (value == 0)
{
return 0;
}
return angle + 180;
}
}