七行核心代码实现第三人称游戏的相机逻辑:
使用到的一些知识:
- 欧拉角
- 虚拟轴
- 四元数计算
- 向量计算
代码实现:
其中RoundMovement方法为核心方法():
using UnityEngine;
/*
*第三人称相机的跟随的逻辑主要有二:
* 1. 鼠标移动改变相机的位置
* 2. 鼠标移动改变相机的旋转角度
*/
public class ThirdPersonalVision1 : MonoBehaviour
{
/// <summary>
/// <para>_offset是一条玩家指向相机方向的向量</para>
/// </summary>
private Vector3 _offset;
/// <summary>
/// <para>存储相机的Transform组件,以方便后续的调用</para>
/// </summary>
private Transform _cameraTransform;
/// <summary>
/// <para>存储玩家的Transform组件,以方便后续的调用</para>
/// </summary>
public Transform playerTransform;
/// <summary>
/// <para>存储虚拟轴“MouseX”的累加值,此累加值用于表示相机在X轴上移动值</para>
/// </summary>
private float _mX;
/// <summary>
/// <para>存储虚拟轴“MouseY”的累加值,此累加值用于表示相机在Y轴上移动值</para>
/// </summary>
private float _mY;
/// <summary>
/// <para>存储虚拟轴“Mouse Scroll”的累加值,用于当作镜头缩放倍率使用,应当设置最大值和最小值</para>
/// </summary>
private float _mScroll;
/// <summary>
/// <para>设置_mScroll的最小值</para>
/// </summary>
public float _mScrollMinNum;
/// <summary>
/// <para>设置_mScroll的最大值</para>
/// </summary>
public float _mScrollMaxNum;
/// <summary>
/// <para>存储旋转的速度</para>
/// </summary>
public float _rotateSpeed;
/// <summary>
/// <para>存储相机需要旋转的四元数</para>
/// </summary>
private Quaternion _mRotation;
/// <summary>
/// <para>存储相机注视玩家旋转所需要的四元数</para>
/// </summary>
private Quaternion _lookRotation;
/// <summary>
/// <para>为变量初始化</para>
/// </summary>
private void Start()
{
_cameraTransform = this.transform;
_offset = _cameraTransform.position - playerTransform.position;
_mScroll = 1f;
//缩放范围试出来的,可以调整
_mScrollMinNum = 0.7f;
_mScrollMaxNum = 2f;
_rotateSpeed = 20f;
}
private void Update()
{
RoundMovement();
}
private void RoundMovement()
{
//获得虚拟轴"Mouse X"累加值
_mX += Input.GetAxis("Mouse X");
//获得虚拟轴"Mouse Y"累减值并限制其取值范围,此处的最大最小值是试出来的
_mY = Mathf.Clamp(_mY-Input.GetAxis("Mouse Y"),-1f,3f);
//获得虚拟轴"Mouse ScrollWheel"的累加值并限制其范围
_mScroll = Mathf.Clamp(_mScroll+Input.GetAxis("Mouse ScrollWheel"), _mScrollMinNum, _mScrollMaxNum);
/*
*关于为什么使用两个鼠标虚拟轴的累加值来充当欧拉角:
* 答:我们想要实现的效果是:当鼠标移动时相机依据鼠标的移动进行环绕旋转。所以相机旋转的角度和鼠标的移动是有密切联系的,使用鼠标虚拟轴作为欧拉角的分量可以建立这种联系。
* 关于为什么只有X和Y的分量,没有Z的分量:
* 答:对于相机旋转而言不需要Z轴的翻滚旋转。
* 关于Quaternion.Euler()方法:
* 答:通过Quaternion.Euler()方法将一个欧拉角转化为一个四元数
*/
_mRotation = Quaternion.Euler(_mY * _rotateSpeed,_mX * _rotateSpeed,0);
/*
*1. _mRotation*_offset是让_offset向量旋转_mRotation角度。
*2. *_mScroll是确定缩放倍率。
*3. +playerTransform.position则是为了确定相机的位置。
*/
_cameraTransform.position = _mRotation * _offset * _mScroll + playerTransform.position;
/*
* 下面为注视游戏物体的方法,可以使用LookAt,也可以自己旋转
*/
//transform.LookAt(_playerTransform);
_lookRotation = Quaternion.LookRotation((playerTransform.position - _cameraTransform.position));
_cameraTransform.rotation =
Quaternion.RotateTowards(_cameraTransform.rotation,_lookRotation,_rotateSpeed * Time.deltaTime * 100f);
}
}