【Unity】实现相机视角跟随

【Unity】实现相机视角跟随

在 Unity 项目中实现相机跟随玩家,保持玩家始终处于镜头中心附近。本文总结 3 种常用方案,并给出各自适用场景与注意事项。

2026-01-30 更新:补充 方法三(推荐):2D 正交相机 SmoothDamp 缓动跟随(LateUpdate + 状态门控)。

目录

  • 方法一:Lerp 平滑跟随(简单通用)
  • 方法二:距离 + 高度 + 旋转阻尼(偏 3D 第三人称)
  • 方法三(推荐):2D 正交 SmoothDamp 缓动跟随(LateUpdate + 状态门控)

方法一:Lerp 平滑跟随(简单通用)

private Transform player;
//玩家和相机的差
private Vector3 offset; 
//相机移动速度
private float speed = 3f;

private void Start() {
    player = GameObject.FindGameObjectWithTag("Player").transform;
    offset = transform.position - player.position;
}

// 更新相机位置
private void LateUpdate() {
    //世界坐标转化为局部坐标
    Vector3 targetPosition = player.position + player.TransformDirection(offset);
    //移动相机
    transform.position = Vector3.Lerp(transform.position, targetPosition, speed * Time.deltaTime);
    //相机看向玩家的方向
    transform.LookAt(player.position);
}

特点

  • 简单易用、效果直观,适合快速验证“跟随是否正确”。

提示(关于 LookAt)

  • LookAt 更适合 3D(或你需要相机始终朝向目标的场景)。
  • 若你是 2D 正交相机:通常不需要 LookAt,保留也不影响“位置跟随”,但可能带来不必要的旋转/朝向变化(尤其当相机本身有其他旋转控制时)。

方法二:距离 + 高度 + 旋转阻尼(偏 3D 第三人称)

public Transform target;

[SerializeField]
private float distance = 10f;//相机与目标距离

[SerializeField]
private float height = 5f;//相机高度

[SerializeField]
private float rotationDamping;//旋转调整速度

[SerializeField]
private float heightDamping;//高度调整速度

private void LateUpdate()
{
    if ((bool)target)
    {
        float y = target.eulerAngles.y;
        float b = target.position.y + height;
        float y2 = base.transform.eulerAngles.y;
        float y3 = base.transform.position.y;
        y2 = Mathf.LerpAngle(y2, y, rotationDamping * Time.deltaTime);
        y3 = Mathf.Lerp(y3, b, heightDamping * Time.deltaTime);
        Quaternion quaternion = Quaternion.Euler(0f, y2, 0f);
        base.transform.position = target.position;
        base.transform.position -= quaternion * Vector3.forward * distance;
        base.transform.position = new Vector3(base.transform.position.x, y3, base.transform.position.z);
        base.transform.LookAt(target);
    }
}

特点

  • 更适合 3D 第三人称:固定距离、固定高度、带旋转阻尼。
  • LookAt 可确保相机一直注视目标。

提示(2D 正交不建议照搬)

  • 该方案使用了绕 Y 轴旋转、距离/高度与 LookAt,属于典型 3D 相机跟随模型。
  • 如果你是 2D 正交,建议优先看本文“方法三”。

方法三(推荐):2D 正交 SmoothDamp 缓动跟随(LateUpdate + 状态门控)

适用场景:2D 正交相机(Orthographic),希望相机跟随玩家位置平移,并表现为“慢跟随/缓冲感”而不是瞬移。

关键点

  • 放在 LateUpdate():通常更不易抖动。
  • 只跟随 X/Y,保持 Z 不变:适配 2D 正交相机。
  • Vector3.SmoothDamp():阻尼缓动更自然。
  • 工程化增强:只在游戏 Playing 状态下跟随,避免加载/暂停/结算阶段相机被错误推动。(若你项目没有状态机,删掉这一段判断即可)

核心代码(来自实际项目落地版本,可直接用)

// 相机跟随(位置缓动)

[Header("=== 相机跟随(位置缓动) ===")]
[SerializeField] private bool enableCameraFollow = true;
[SerializeField] private float cameraFollowSmoothTime = 0.25f;   // 越大越慢
[SerializeField] private float cameraFollowMaxSpeed = 0f;         // <=0 不限制
[SerializeField] private Vector2 cameraFollowOffsetXY = Vector2.zero;

private Vector3 cameraFollowVelocity = Vector3.zero;
public Transform followTarget; // 绑定玩家 Transform(或运行时赋值)

private void LateUpdate()
{
    if (!enableCameraFollow) return;
    if (followTarget == null) return;

    // 如果你有游戏状态机,可加“Playing 才跟随”
    // if (!IsPlaying) return;

    Camera cam = Camera.main;
    if (cam == null) return;

    Vector3 camPos = cam.transform.position;
    Vector3 targetPos = followTarget.position;

    Vector3 desiredPos = new Vector3(
        targetPos.x + cameraFollowOffsetXY.x,
        targetPos.y + cameraFollowOffsetXY.y,
        camPos.z
    );

    float smoothTime = Mathf.Max(0.001f, cameraFollowSmoothTime);
    float maxSpeed = cameraFollowMaxSpeed > 0f ? cameraFollowMaxSpeed : Mathf.Infinity;

    cam.transform.position = Vector3.SmoothDamp(
        camPos,
        desiredPos,
        ref cameraFollowVelocity,
        smoothTime,
        maxSpeed,
        Time.deltaTime
    );
}

参数建议

  • cameraFollowSmoothTime:0.15 ~ 0.35 常用(越大越“慢跟随”)
  • cameraFollowOffsetXY:可用于让玩家偏下/偏左以露出前方视野
  • cameraFollowMaxSpeed:一般不需要限制;远距离追赶太快时可设置上限

常见问题

为什么用 LateUpdate?

LateUpdate 在大多数 Update 之后执行,能让相机在“玩家本帧位移完成后”再跟随,减少抖动概率。

posted @ 2023-04-04 15:00  星空探险家  阅读(68)  评论(0)    收藏  举报  来源