Unity官方的Cinemachine工具,功能非常强大并且方便使用,可以用其轻松实现各种相机的功能。本文介绍一种简单快速实现锁定敌人功能的第三人相机方案。效果如下图所示
实现步骤介绍
1.准备Unity2018.3以上的版本,新建一个空白的3d项目,在Pakage Manager中下载安装Cinemachine(本文使用的是Unity2019.3.0f3 + Cinemachine 2.3.4)
2.新建一个第三人称虚拟相机Cinemachine FreeLook,一个名为Follow的空物体,一个名为LookAt的空物体。为使Hierarchy保持整洁,新建一个名为CameraRoot的空物体,将上述三者和Main Camera都纳入其下。
3.设置CM FreeLook的基本属性
将CM FreeLook的Follow设置为Follow空物体,LookAt设置为LookAt空物体(这里为何不将Follow直接设置为玩家本身,不将LookAt直接设置为要锁定的敌人呢?放到后面具体实现的时候来说明)。其余项目可以保持默认值。
4.设置CM FreeLook两条轴的属性
- Y Aixs的Value设置成1,并且始终保持不变。本方案始终使用TopRig的设置,不会用到MiddleRig和BottomRig。
- 将X Aixs和Y Aixs的InputAxisName中的MouseX和MouseY去掉。本方案不使用鼠标手动操作XY轴的运动。
- 将Orbits下的Binding Mode设置为Lock To Target With World Up。无论Follow对象如何旋转,围绕Follow的旋转轴始终朝向世界坐标的Up方向,即旋转轨迹面始终平行于世界坐标的水平平面。
5.设置CM FreeLook的运动属性
- TopRig中的Body属性下的XYZ Damping是在三个轴的方向上虚拟相机位置跟随Follow物体的缓冲值,可根据实际需求设置。0为不缓冲,保持相机旋转轴中心的位置坐标和Follow对象始终保持一致。本方案不需要位置跟随上的缓冲,因此均设置为0。
- YawDamping是相机Yaw轴(可以简单理解成y轴方向)旋转值跟随Follow的旋转值的缓冲值,0表示不缓冲,可根据实际需求设置。本方案中将其设置为0.2。
- Aim属性下的各项属性基本保持默认即可。本方案的设置如图所示。
6.建立一个Player物体和若干个Enemy物体。
物体的形状可以随意设定,本文为了方便就设置为胶囊形,并添加一个小球放在Z轴正方向表示物体的前方。
7.编写相机控制脚本
新建一个CameraController用于控制相机跟随。将其添加到CameraRoot上,并设置好各项属性。
using UnityEngine;
using Cinemachine;
public class CameraController : MonoBehaviour
{
[SerializeField]
private CinemachineFreeLook CmFreeLook;
[SerializeField]
private Transform follow;
[SerializeField]
private Transform lookAt;
[SerializeField]
private Transform player;
[SerializeField]
private Transform[] enemies;
[SerializeField]
private AimMark aimMark;
// 当前锁定的敌人的Index
private int lockedEnemyIndex;
private void Start()
{
// 给FreeLook虚拟相机设置Follow和LookAt的物体
CmFreeLook.Follow = follow;
CmFreeLook.LookAt = lookAt;
// 设置锁定标记的跟随对象
aimMark.SetAimTarget(lookAt);
}
private void Update()
{
// 按下空格时切换锁定的敌人
if(Input.GetKeyDown(KeyCode.Space))
{
lockedEnemyIndex = (lockedEnemyIndex + 1) % enemies.Length;
aimMark.PlayAimAnimation();
}
// 使lookAt的位置和旋转都和锁定的目标保持一致
lookAt.position = enemies[lockedEnemyIndex].position;
lookAt.rotation = enemies[lockedEnemyIndex].rotation;
// 使follow的位置和玩家一致
follow.position = player.position;
// 使follow的z轴正方向指向lookAt
follow.LookAt(lookAt);
}
}
其中的AimMark
是锁定的时候出现的UI,和相机功能无关,这里可以先不看。
这里将LookAt空物体的位置和旋转始终保持和锁定中的敌人一致,Follow则是位置保持和Player一致同时使Z轴正方向指向LookAt。
上文提到,为何不直接将CM FreeLook的Follow和LookAt直接设置为Player和锁定中Enemy,而是需要用两个间接物体呢?
建立一个Follow空物体,位置跟随Player,并看向LookAt物体的目的是为了使相机,Player,Enemy处于一条直线上
Orbits中的Binding Mode设置为Lock To Tartget后,相机的旋转轴的位置跟随Follow对象的位置,旋转值也会Follow对象的旋转值。
而Lock To Target的三种变体,相机的旋转轴的位置都是跟随Follow对象的位置,但旋转值的跟随方式则有所不同
Lock To Tartget: 旋转值跟随Follow对象的旋转值
Lock To Target On Assign: Start时或Follow对象更变时,旋转值设置为Follow对象的旋转值一次,之后则不再变化。
Lock To Target With World Up: 只有Yaw轴的旋转值跟随Follow对象的旋转值。
Lock To Target No Roll: Pitch轴和Yaw轴跟随Follow对象的旋转值,Roll轴不跟随
建立一个LookAt空物体的目的,是为了让切换锁定敌人时,镜头能平滑转向。
直接更换CM FreeLook的LookAt对象的话,镜头会瞬间指向对象,不会对其进行补间。而让LookAt对象始终为一个空物体,切换锁定时让空物体的位置更变为锁定敌人的位置,相机的转向就会进行补间。
8.要点总结
- 使用Cinemachine中的FreeLook相机,Follow和LookAt属性分别设置为Follow空物体和LookAt空物体。
- 设置Orbits下的Binding Mode为Lock To Target With World Up。
- 编写脚本,使Follow空物体位置跟随Player,旋转指向LookAt空物体。LookAt空物体位置和旋转都跟随要锁定的Enemy。
以上就是使用Cinemachine快速实现具有锁定敌人功能的第三人称相机方案。