实际上,Unity官方内置了一个相机运动的包Cinemachine
,功能非常丰富。但是对于只想要一个简单的相机跟随效果的开发者来说,有些杀鸡用牛刀了。因此,下面将介绍一个简单的脚本来实现跟随效果。
最简单的跟随方法是直接将相机设为角色的子物体,就可以实时相机跟随玩家了。但是这样展示出的效果太过生硬,画面表现力也不是很好,因此需要一种看起来不那么生硬的方法。
通过查阅Unity中文文档中Vector2
的内容,我们可以找到SmoothDamp
方法,它的作用如下图所示:
也就是说可以使某物体平滑的移动到某个位置,这不正是我们想要的效果吗。在FixedUpdate()
中调用该方法,则有:
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform target; // 跟随目标
[Range(0.001f, 0.1f)]
public float smoothSpeed; // 平滑度,值越小,移动越快
[Range(0.05f, 0.5f)]
public float maxVelocity; // 最大速度
[Range(0.1f, 10f)]
public float moveSpeed; // 控制最后移动速度
private Vector2 curSpeed;
private Vector2 targetPos => target.position;
private void FixedUpdate()
{
Vector2.SmoothDamp(transform.position, targetPos, ref curSpeed,
smoothSpeed, maxVelocity, Time.fixedDeltaTime);
transform.position += (Vector3)curSpeed * moveSpeed;
}
}
以上脚本可以初步完成自己想要的效果了。但是运行后会发现相机有时会鬼畜(剧烈抖动),这显然不是我们想要的效果,更不希望玩家所看见。该如何解决呢?通过观察我们发现,相机每次进行鬼畜时x,y轴变化值都在(-0.1f,0.1f)
之间(变化值范围不一定相同,可能更小,这与之前设置的变量值有关)。这个区间内的变化值很小,人用肉眼很难分辨出来,因此我们可以采取如果相机与角色的x,y轴距离小于这个值,直接将玩家对应的x或y轴坐标赋值给相机,就解决了抖动的问题。
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform target;
[Range(0.001f, 0.1f)]
public float smoothSpeed;
[Range(0.05f, 0.5f)]
public float maxVelocity;
[Range(0.1f, 10f)]
public float moveSpeed;
[Range(0.01f, 1f)]
public float min_x;
[Range(0.01f, 1f)]
public float min_y;
private Vector2 curSpeed;
private Vector2 targetPos => target.position;
private Vector3 camPos { get => transform.position; set { } }
private void FixedUpdate()
{
camPos = new Vector3(
Distance(camPos.x, targetPos.x) < min_x ? targetPos.x : camPos.x,
Distance(camPos.y, targetPos.y) < min_y ? targetPos.y : camPos.y,
camPos.z);
Vector2.SmoothDamp(transform.position, targetPos, ref curSpeed,
smoothSpeed, maxVelocity, Time.fixedDeltaTime);
transform.position += (Vector3)curSpeed * moveSpeed;
}
public float Distance(float x, float y) => Mathf.Abs(x - y);
}
除此以外,如果角色移动过快,出现摄像机跟随不上角色的情况,也可以添加一个变量用于控制摄像机的速度随相机与角色之间距离变化而变化,这里就不再展示了。
最后效果如下图: