CameraController

来源:互联网 发布:汽车产业网络平台 编辑:程序博客网 时间:2024/06/11 11:29

  看到不少同学都想写一个CameraController,但是又各种转来转去出错的,今天就得空写一个例子,分享一下这其中需要了解的知识。

  首先要了解向量的基本操作,向量旋转:四元素×向量

举个简单例子:定义一个初始值为(0,0,1)的向量:

private Vector3 targetPos = Vector3.forward;

  为了清楚的看清向量的旋转,我们将此向量画出来:

Debug.DrawLine(Vector3.zero, targetPos);

  OK,从Unity的Top视角来看,应该是这样的:


  接下来我们将此向量绕Y轴顺时针旋转45度:

Quaternion qua1 = Quaternion.Euler(0, 45, 0);

targetPos = qua1 * Vector3.forward;

  得到的向量是这样的:

  当然,你也可以任性的乘N个:

Quaternion qua1 = Quaternion.Euler(0, 45, 0);
Quaternion qua2 = Quaternion.Euler(45, 0, 0);
targetPos = qua1 * qua2 * Vector3.forward;

  OK,有了以上基础,我们来实现摄像机的控制。想想一下,如果玩家站在原点,我们来转动一个点,最后把Camera放到我们旋转后的位置,最后让Camera看向玩家,是不是有点思路了。

  当然这个时候运行代码,玩家只能站在原点,因为你会发现如果不在原点摄像机就乱转了。其实原因很简单,那是因为我们始终是把一个点绕着(0,0,0)点来转,而不是玩家。那么如果我们知道了玩家的位置,是不是就可以绕玩家来转了。那玩家的位置是又是什么呢。我想你几乎可以脱口而出,不就是player.position嘛。

  好了,思路就是这样,自己加了一些其他的小细节。当然,万变不离其宗,上代码

<span style="font-family:KaiTi_GB2312;font-size:18px;">using UnityEngine;public class CameraController : MonoBehaviour {/// <summary>/// 跟随目标/// </summary>public Transform Target;/// <summary>/// Distance between target and me/// </summary>public float Dis = 5;/// <summary>/// 最大转动速度/// </summary>public int MaxRotSpeed = 100;/// <summary>/// Y轴转动角度范围/// </summary>public float YMaxAngel = 30f;public float YMinAngel = -60f;/// <summary>/// 转动阻尼/// </summary>public int RotDamping = 5;/// <summary>/// Y轴跟随阻尼/// </summary>public int YFollowDamping = 3;/// <summary>/// 默认绕X旋转角度/// </summary>private int DefaultX = -8;/// <summary>/// 高度偏移/// </summary>public Vector3 OffHeight = new Vector3(0, 1, 0);/// <summary>/// 注视目标点/// </summary>public Vector3 TargetPos {get {return Target.position + OffHeight;}}/// <summary>/// 角速度/// </summary>private float XRotSpeed;private float YRotSpeed;/// <summary>/// 转动角度/// </summary>private float xRot;private float yRot;private Transform myTrans;public void Start() {myTrans = transform;//Camera初始位置在target的后方Vector3 originDir = -Target.forward;Quaternion qua = Quaternion.LookRotation(originDir);yRot = qua.eulerAngles.y;xRot = DefaultX;}private Quaternion qua;private Vector3 newPos;public void Update() {CameraMove();}private void CameraMove() {//获取旋转速度XRotSpeed = Mathf.Lerp(XRotSpeed, Input.GetAxis("Mouse Y") * MaxRotSpeed, 1f / RotDamping);YRotSpeed = Mathf.Lerp(YRotSpeed, Input.GetAxis("Mouse X") * MaxRotSpeed, 1f / RotDamping);//计算旋转角度xRot += XRotSpeed * Time.deltaTime;yRot += YRotSpeed * Time.deltaTime;//限制范围xRot = Mathf.Clamp(xRot, YMinAngel, YMaxAngel);yRot = Mathf.Repeat(yRot, 360);qua = Quaternion.Euler(new Vector3(xRot, yRot, 0));//向量Vector3.forward * Dis旋转qua后,+ TargetPos,即为最终Camera的位置newPos = TargetPos + qua * Vector3.forward * Dis;//Y轴延迟跟随newPos.y = Mathf.Lerp(myTrans.position.y, newPos.y, 1f / YFollowDamping);//更新Camera位置并看向目标myTrans.position = newPos;myTrans.LookAt(TargetPos);}public void SetTarget(Transform tgt) {Target = tgt;}}</span>

  将此脚本挂在Camera上,然后选择要观察的物体

Target,点击运行就可以看效果啦!

  可以看到,核心的一步就是:

newPos = TargetPos + qua * Vector3.forward * Dis;

  也就是我们今天讲的一个知识点,是不是很简单呢。OK,注释已经很详细了,这里就不多做解释。有问题可以留言讨论哦!

1 0