Unity中如何为transform.RotateAround实现Lerp平滑旋转?
解决Transform.RotateAround()的平滑旋转问题
无法直接给transform.RotateAround()添加Lerp平滑效果——因为这个方法是即时修改相机的位置和旋转,没有预留插值的中间状态。要实现绕目标点的平滑旋转,需要换个思路:先计算相机最终要到达的目标位置/旋转,再通过插值让相机平滑过渡到该状态。
实现思路
- 维护一个目标旋转变量,用来记录相机应该转到的朝向(而非直接修改相机Transform)
- 根据鼠标输入更新这个目标旋转(绕目标点的Y轴旋转)
- 在每一帧中,根据目标旋转计算相机的目标位置,再用
Vector3.Lerp或Vector3.SmoothDamp平滑位置,用Quaternion.Lerp或Quaternion.SmoothDamp平滑旋转
完整代码示例
1. 定义变量
public Transform RotationTarget; // 要绕转的目标物体 public bool EnableRotation; public float RotationSpeed = 5f; // 旋转速度 public float RotationDampening = 10f; // 平滑系数(值越大过渡越快) public float CameraDistance = 5f; // 相机与目标点的固定距离 private Quaternion _targetRotation; // 相机的目标旋转 private Vector3 _positionVelocity; // SmoothDamp用的速度变量 private Quaternion _rotationVelocity; // SmoothDamp用的旋转速度变量
2. 处理鼠标输入更新目标旋转
private void HandleRotationInput() { if (!EnableRotation || RotationTarget == null) return; // 重置旋转到初始朝向 if (Input.GetKeyDown(KeyCode.R)) { _targetRotation = Quaternion.LookRotation(RotationTarget.position - transform.position); } // 按住右键时更新目标旋转 if (Input.GetKey(KeyCode.Mouse1)) { float xInput = Input.GetAxis("Mouse X"); // 绕目标点的Y轴旋转目标旋转值 _targetRotation *= Quaternion.Euler(Vector3.up * RotationSpeed * xInput); } }
3. 平滑过渡到目标状态
这里提供两种平滑方式,选一种即可:
方式一:用Lerp(简单直接)
private void Update() { HandleRotationInput(); if (RotationTarget == null) return; // 计算相机的目标位置:从目标点出发,沿目标旋转的反方向(看向目标)移动指定距离 Vector3 targetPosition = RotationTarget.position - _targetRotation * Vector3.forward * CameraDistance; // 平滑位置 transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * RotationDampening); // 平滑旋转(确保相机始终看向目标) Quaternion lookAtRotation = Quaternion.LookRotation(RotationTarget.position - transform.position); transform.rotation = Quaternion.Lerp(transform.rotation, lookAtRotation, Time.deltaTime * RotationDampening); }
方式二:用SmoothDamp(更自然的平滑效果)
private void Update() { HandleRotationInput(); if (RotationTarget == null) return; Vector3 targetPosition = RotationTarget.position - _targetRotation * Vector3.forward * CameraDistance; // 平滑位置,1/RotationDampening是平滑时间 transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref _positionVelocity, 1f / RotationDampening); // 计算看向目标的旋转,再平滑过渡 Quaternion targetRotation = Quaternion.LookRotation(RotationTarget.position - transform.position); transform.rotation = Quaternion.SmoothDamp(transform.rotation, targetRotation, ref _rotationVelocity, 1f / RotationDampening); }
为什么原方法不行?
transform.RotateAround()是直接修改相机的Transform组件,每帧执行时会立刻把相机移动到新位置/旋转,没有给插值算法留下中间状态的空间。而上面的方法是先确定"要去哪",再让相机逐步移动过去,自然就能实现平滑效果。
内容的提问来源于stack exchange,提问作者bonanzaa
相关产品推荐
相关产品推荐

