Unity中如何实现围绕定点朝向目标位置的旋转方法?
自定义Unity RotateAroundTowards方法实现
Unity内置的Transform.RotateAround是每帧按固定角度旋转,而我们需要的RotateAroundTowards要在指定时长内,围绕固定点从当前位置平滑旋转到终点位置。核心思路是先计算旋转所需的总角度,再按时长均匀分配旋转速度完成运动。
实现核心步骤
- 计算当前位置、终点位置到固定点的向量,获取旋转半径
- 修正终点位置到与当前位置同半径的圆周上(避免原终点距离固定点过远/过近导致偏移)
- 计算两个向量间的带符号夹角,确定总旋转角度与方向
- 通过协程逐帧更新旋转进度,在指定时长内完成位置过渡
完整代码实现
using UnityEngine; using System.Collections; public class RotationUtility : MonoBehaviour { // 自定义方法:围绕固定点在指定时长内旋转到目标位置 public IEnumerator RotateAroundTowards(Vector3 currentPosition, Vector3 fixedPoint, Vector3 endPosition, float durationInSeconds) { // 边界处理:当前位置与固定点重合,无法执行旋转 if (Vector3.Distance(currentPosition, fixedPoint) < 0.001f) { Debug.LogWarning("当前位置与固定点重合,无法执行旋转操作"); yield break; } // 计算当前到固定点的向量与旋转半径 Vector3 currentDir = currentPosition - fixedPoint; float rotationRadius = currentDir.magnitude; // 修正终点位置到同一半径的圆周上 Vector3 targetDir = endPosition - fixedPoint; targetDir = targetDir.normalized * rotationRadius; Vector3 correctedEndPos = fixedPoint + targetDir; // 计算总旋转角度(带符号,确保旋转方向正确) float totalRotationAngle = Vector3.SignedAngle(currentDir, targetDir, Vector3.up); // 边界处理:已接近目标位置,无需旋转 if (Mathf.Abs(totalRotationAngle) < 0.1f) { yield break; } // 计算每秒旋转速度 float rotationSpeedPerSecond = totalRotationAngle / durationInSeconds; float elapsedTime = 0f; // 逐帧更新旋转位置 while (elapsedTime < durationInSeconds) { elapsedTime += Time.deltaTime; float frameRotation = rotationSpeedPerSecond * Time.deltaTime; // 旋转当前方向向量 currentDir = Quaternion.AngleAxis(frameRotation, Vector3.up) * currentDir; // 更新当前位置 currentPosition = fixedPoint + currentDir; // 此处将计算出的位置赋值给目标对象 // 示例:targetTransform.position = currentPosition; yield return null; } // 最后修正到精确终点位置,消除累计误差 currentPosition = correctedEndPos; // targetTransform.position = currentPosition; } // 调用示例(在MonoBehaviour脚本中) public void StartTargetedRotation() { Vector3 currentPos = transform.position; Vector3 fixedPoint = new Vector3(0, 0, 0); Vector3 targetPos = new Vector3(5, 0, 5); float rotateDuration = 3f; StartCoroutine(RotateAroundTowards(currentPos, fixedPoint, targetPos, rotateDuration)); } }
关键细节说明
- 半径修正:强制让终点位置落在当前位置的旋转圆周上,保证运动轨迹是标准圆弧
- 带符号角度:使用
Vector3.SignedAngle确保旋转方向正确(顺时针/逆时针) - 协程控制:通过协程简化时间跟踪逻辑,实现平滑的时长控制
- 边界判断:提前处理无效场景,避免报错和无意义计算
内容的提问来源于stack exchange,提问作者Richard Kennard
相关产品推荐
相关产品推荐

