You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot 3中降低环绕旋转物体转速的问题求助

问题分析与解决方案

你遇到的旋转速度过快问题,核心原因有两个:

  • dtheta 没有乘以 delta 时间,导致旋转速度完全依赖游戏帧率,帧率越高转得越快,且固定步长本身数值偏大。
  • rotationLimit 是旋转的总角度上限,和速度无关,改它只会改变最终旋转的角度,不会影响转动快慢。

具体修改步骤:

  1. 改用基于时间的旋转速度:定义一个每秒旋转的角度(比如rotation_speed = PI/2表示每秒转90度),替换原来的固定dtheta,更新角度时乘以delta,让速度不受帧率影响。
  2. 保存初始旋转偏移:进入ROTATE状态时,先保存Box B相对于Box A的初始偏移量,避免每次循环重新计算偏移导致逻辑混乱。
  3. 设置正确的旋转上限:如果需要旋转180度,把rotationLimit设为PI(π弧度等于180度)。

修改后的完整脚本:

var rotation_origin
export var r = 1
var transition_point = Vector3.ZERO
var theta 
# 替换固定dtheta为基于时间的旋转速度,单位:弧度/秒
var rotation_speed = PI/2  # 每秒转90度,可根据需求调整
var rotationLimit = PI  # 180度,对应你需要的旋转角度
var boxA 
var boxB
var stopping_distance = 1.0
var velocity = Vector3.ZERO
var move_speed = 2.0
var blend_timer = 0.0
var blend_duration = 7.0  # 调整混合时长


var state = states.IDLE

enum states {
    IDLE,
    SEEK,
    ROTATE
}

func _ready():
    boxA = get_node("../boxA")
    boxB = get_node("../boxB")
    
func _process(delta):
    rotateAround(delta)

func rotateAround(delta):
    match state:
        states.IDLE:
            var direction_to_player = boxA.global_transform.origin - global_transform.origin
            var distance_to_player = direction_to_player.length()
            if distance_to_player < stopping_distance:
                velocity = Vector3.ZERO
            else:
                state = states.SEEK
        
        states.SEEK:
            var direction_to_player = boxA.global_transform.origin - global_transform.origin
            var distance_to_player = direction_to_player.length()
            direction_to_player = direction_to_player.normalized()
            
            if distance_to_player > stopping_distance:
                velocity = direction_to_player * move_speed
                move_and_slide(velocity)
            elif distance_to_player < stopping_distance:
                state = states.ROTATE
                # 进入旋转状态时,初始化theta为0,保存初始偏移量
                theta = 0
                rotation_origin = boxB.global_transform.origin - boxA.global_transform.origin
        
        states.ROTATE:
            # 基于时间更新角度
            theta += rotation_speed * delta

            if theta <= rotationLimit:
                var cosTheta = cos(theta)
                var sinTheta = sin(theta)
                # 使用初始偏移量计算新位置
                var rotated_offset = Vector2(
                    cosTheta * rotation_origin.x - sinTheta * rotation_origin.z,
                    sinTheta * rotation_origin.x + cosTheta * rotation_origin.z
                )

                boxB.transform.origin = boxA.global_transform.origin + Vector3(rotated_offset.x, 0, rotated_offset.y)
            else:
                theta = rotationLimit  # 停在旋转上限角度
                state = states.IDLE

额外说明:

  • 调整rotation_speed的数值可以控制旋转快慢:数值越大转得越快,比如PI就是每秒转180度,PI/4就是每秒转45度。
  • 删除了原代码中无效的空rotationLimit语句。

内容的提问来源于stack exchange,提问作者Chris33556

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:37:05