先上效果图:
把缩放和旋转分开说吧
缩放:
原理很简单:
1.先保存相机与玩家的的位置偏移offset
2.获取用户输入(滚轮)
3.将滚轮输入乘一个合理的系数,也可以称为缩放速度啦
4.将offset数值更新
ps:第四步用到了vector3.normalized,首先获取到offset的单位向量,再将它放大
pps:可以使用vector3.magnitude获取偏移向量offset的模(向量长度),通过模来限制最大缩放和最小缩放
void ScrollView()
{
//限制最大缩放
if (Input.GetAxis("Mouse ScrollWheel") < 0 && offsetPlayerPos.magnitude < maxScroll)
{
//获取偏移量的模
distance = offsetPlayerPos.magnitude;
distance += System.Math.Abs(Input.GetAxis("Mouse ScrollWheel")) * scrollSpeed;
//通过获得单位向量*新的偏移模更新偏移信息
offsetPlayerPos = offsetPlayerPos.normalized * distance;
}
//限制最小缩放
if (Input.GetAxis("Mouse ScrollWheel") > 0 && offsetPlayerPos.magnitude > minScroll)
{
//获取偏移量的模
distance = offsetPlayerPos.magnitude;
distance += -System.Math.Abs(Input.GetAxis("Mouse ScrollWheel")) * scrollSpeed;
//通过获得单位向量*新的偏移模更新偏移信息
offsetPlayerPos = offsetPlayerPos.normalized * distance;
}
}
旋转:
原理很简单:
先讲左右旋转(Mouse X)
1.获取用户输入Input.GetAxis("Mouse X")
2.将摄像机绕着玩家,以玩家的y轴进行旋转
3.旋转完成,更新偏移信息offset
ps:这里左右旋转我认为不需要限制
transform.RotateAround(playerTransform.position, playerTransform.up, Input.GetAxis("Mouse X") * rotateSpeed);
//更新玩家与摄像机的偏移信息
offsetPlayerPos = transform.position - playerTransform.position;
transform.position = playerTransform.position + offsetPlayerPos;
再来上下旋转(Mouse Y)
1.获取用户输入Input.GetAxis("Mouse Y")
2.将摄像机绕着玩家,以摄像机的X轴进行旋转(这是个坑,一开始绕着玩家的X轴发现很奇怪,因为玩家的位置时刻变化,导致一些诡异效果,因为我摄像机使用了LookAt所以保证摄像机的做圆周运动)
3.旋转完成,更新偏移信息offset
ps:这个上下旋转的角度我使用vector3.localEulerAngles.x获取角度大小从而限制最大值与最小值
if (Input.GetMouseButton(1))
{
//限制最大角度
if (transform.localEulerAngles.x < maxYRotateAngles && Input.GetAxis("Mouse Y") < 0)
{
transform.RotateAround(playerTransform.position, transform.right, -Input.GetAxis("Mouse Y") * rotateSpeed);
//更新玩家与摄像机的偏移信息
offsetPlayerPos = transform.position - playerTransform.position;
transform.position = playerTransform.position + offsetPlayerPos;
}
//限制最小角度
if (transform.localEulerAngles.x > minYRotateAngles && Input.GetAxis("Mouse Y") > 0)
{
transform.RotateAround(playerTransform.position, transform.right, -Input.GetAxis("Mouse Y") * rotateSpeed);
//更新玩家与摄像机的偏移信息
offsetPlayerPos = transform.position - playerTransform.position;
transform.position = playerTransform.position + offsetPlayerPos;
}
}
完整代码如下:挂到Camera上即可,可通过inspector面板调节各参数
public class CameraController : MonoBehaviour {
public float maxScroll;
public float minScroll;
public float maxYRotateAngles = 70;
public float minYRotateAngles = 5;
public float rotateSpeed = 5;
public float scrollSpeed = 10;
private Transform playerTransform;
private Vector3 offsetPlayerPos;
private float distance;
private Quaternion currentRotation;
void Start()
{
playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
transform.LookAt(playerTransform);
offsetPlayerPos = transform.position - playerTransform.position;
}
void Update()
{
transform.position = playerTransform.position + offsetPlayerPos;
RotateCamera();
ScrollView();
}
void RotateCamera()
{
if (Input.GetMouseButton(1))
{
transform.RotateAround(playerTransform.position, playerTransform.up, Input.GetAxis("Mouse X") * rotateSpeed);
//更新玩家与摄像机的偏移信息
offsetPlayerPos = transform.position - playerTransform.position;
transform.position = playerTransform.position + offsetPlayerPos;
//限制最大角度
if (transform.localEulerAngles.x < maxYRotateAngles && Input.GetAxis("Mouse Y") < 0)
{
transform.RotateAround(playerTransform.position, transform.right, -Input.GetAxis("Mouse Y") * rotateSpeed);
//更新玩家与摄像机的偏移信息
offsetPlayerPos = transform.position - playerTransform.position;
transform.position = playerTransform.position + offsetPlayerPos;
}
//限制最小角度
if (transform.localEulerAngles.x > minYRotateAngles && Input.GetAxis("Mouse Y") > 0)
{
transform.RotateAround(playerTransform.position, transform.right, -Input.GetAxis("Mouse Y") * rotateSpeed);
//更新玩家与摄像机的偏移信息
offsetPlayerPos = transform.position - playerTransform.position;
transform.position = playerTransform.position + offsetPlayerPos;
}
}
}
void ScrollView()
{
//限制最大缩放
if (Input.GetAxis("Mouse ScrollWheel") < 0 && offsetPlayerPos.magnitude < maxScroll)
{
//获取偏移量的模
distance = offsetPlayerPos.magnitude;
distance += System.Math.Abs(Input.GetAxis("Mouse ScrollWheel")) * scrollSpeed;
//通过获得单位向量*新的偏移模更新偏移信息
offsetPlayerPos = offsetPlayerPos.normalized * distance;
}
//限制最小缩放
if (Input.GetAxis("Mouse ScrollWheel") > 0 && offsetPlayerPos.magnitude > minScroll)
{
//获取偏移量的模
distance = offsetPlayerPos.magnitude;
distance += -System.Math.Abs(Input.GetAxis("Mouse ScrollWheel")) * scrollSpeed;
//通过获得单位向量*新的偏移模更新偏移信息
offsetPlayerPos = offsetPlayerPos.normalized * distance;
}
}
}