rotate_toward
2026/4/15大约 3 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — rotate_toward
rotate_toward
定义
rotate_toward() 的作用是:把当前角度向目标角度"旋转"一定步长,但每帧最多只能转指定的最大角度。
打个比方:想象一个旋转门。你想从当前位置转到对面(目标角度),但旋转门有速度限制——每秒最多只能转 30 度。rotate_toward() 就像一个自动驾驶员:你告诉它"我现在面朝哪里"(current)、"我想面朝哪里"(target)和"每帧最多转多少"(max_step),它帮你算出"当前帧应该转到哪个位置"。
这个函数会自动选择最短路径——如果目标在左边更近,就往左转;如果右边更近,就往右转。而且当已经到达(或超过)目标时,它会直接返回目标值,不会"转过头"。
函数签名
C#
// 使用 Godot 的 Mathf
public static float RotateToward(float current, float target, float maxStep)GDScript
func rotate_toward(current: float, target: float, max_step: float) -> float参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
| current | float | 是 | 当前角度,单位是弧度(不是度) |
| target | float | 是 | 目标角度,单位是弧度(不是度) |
| max_step | float | 是 | 每次调用的最大旋转步长,单位是弧度。必须 >= 0 |
返回值
类型: float
返回新的角度值(弧度)。规则如下:
| 情况 | 返回值 | 说明 |
|---|---|---|
| 目标角度就在最大步长以内 | target | 直接到目标,不会"转过头" |
| 目标角度超过最大步长 | current +/- max_step | 按最大步长向目标靠近一步 |
| max_step 为 0 | current | 不旋转,保持原角度 |
| max_step 为负数 | current | 负步长视为不旋转 |
代码示例
下面是一个炮台自动追踪玩家的例子——炮台每帧最多旋转 2 弧度(约 115 度),平滑地转向玩家:
C#
using Godot;
public partial class Turret : Node2D
{
// 导出属性:炮台的最大旋转速度(弧度/秒)
[Export] public float ExRotateSpeed = 2.0f;
// 内部变量:目标节点(玩家)
private Node2D _target;
public override void _Ready()
{
// 假设玩家在场景中
_target = GetParent().GetNode<Node2D>("Player");
}
public override void _Process(double delta)
{
if (_target == null) return;
// 计算朝向玩家的目标角度
float targetAngle = (_target.GlobalPosition - GlobalPosition).Angle();
// 计算当前帧最大旋转步长(弧度/秒 * 秒 = 弧度)
float maxStep = ExRotateSpeed * (float)delta;
// 平滑旋转:从当前角度向目标角度转,每帧最多转 maxStep
float newAngle = Mathf.RotateToward(Rotation, targetAngle, maxStep);
Rotation = newAngle;
GD.Print($"炮台角度: {Mathf.RadToDeg(Rotation):F1} 度");
}
}GDScript
extends Node2D
## 导出属性:炮台的最大旋转速度(弧度/秒)
@export var ex_rotate_speed: float = 2.0
## 内部变量:目标节点(玩家)
var _target: Node2D
func _ready() -> void:
# 假设玩家在场景中
_target = get_parent().get_node("Player")
func _process(delta: float) -> void:
if _target == null:
return
# 计算朝向玩家的目标角度
var target_angle := (_target.global_position - global_position).angle()
# 计算当前帧最大旋转步长(弧度/秒 * 秒 = 弧度)
var max_step := ex_rotate_speed * delta
# 平滑旋转:从当前角度向目标角度转,每帧最多转 max_step
var new_angle := rotate_toward(rotation, target_angle, max_step)
rotation = new_angle
print("炮台角度: %.1f 度" % rad_to_deg(rotation))注意事项
- 所有角度都是弧度:
rotate_toward()使用弧度,不是度数。如果你习惯用度数思考,可以用Mathf.DegToRad()转换输入,用Mathf.RadToDeg()转换输出。 - 自动走最短路径:这个函数会自动选择从
current到target的最短弧线路径。比如当前是 170 度,目标是 -170 度,它会走 20 度那条短路(跨过 180 度),而不是走 340 度那条长路。 - 不会"转过头":当
current和target的差距小于max_step时,函数直接返回target,不会超过目标再转回来。这让"到达后停下来"非常自然。 - 与
lerp()/lerp_angle()的区别:lerp()是线性插值,按百分比靠近目标,没有速度限制的概念lerp_angle()和lerp()类似但处理了角度环绕rotate_toward()是按固定最大步长靠近,更适合"匀速旋转"的需求
- max_step 必须非负:如果传入负数,函数不会旋转(直接返回 current)。
