Unity实用案例之——CameraController

  看到不少同学都想写一个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,注释已经很详细了,这里就不多做解释。有问题可以留言讨论哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值