如何用Godot 4与GDScript实现坦克炮塔跟随相机的平滑旋转?
解决方案
核心问题在于炮塔作为坦克的子节点,会继承坦克的旋转。要实现炮塔跟随相机且不受坦克转向影响,需要让炮塔的全局旋转角度对齐相机的全局水平旋转,同时抵消父节点(坦克)的旋转影响。
步骤1:在相机脚本中记录全局水平旋转角度
修改相机的脚本,保存相机的全局Y轴旋转值(仅水平方向旋转):
var camera_global_yaw: float = 0.0 func _ready(): Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) set_as_top_level(true) camera_global_yaw = global_rotation.y func _input(event: InputEvent): if event is InputEventMouseMotion: # 保留你原本的相机旋转逻辑,示例如下: rotate_y(-event.relative.x * 0.01) camera_global_yaw = global_rotation.y
步骤2:给炮塔添加独立旋转脚本
在炮塔的脚本中,每帧计算抵消坦克旋转后的局部角度,同时实现平滑跟随:
@export var smooth_speed: float = 5.0 # 数值越大,跟随灵敏度越高 var target_local_yaw: float = 0.0 func _process(delta: float): # 获取坦克的全局Y轴旋转角度 var tank_global_yaw: float = get_parent().global_rotation.y # 获取相机的目标全局Y轴角度 var target_global_yaw: float = get_node("/root/Camera3D").camera_global_yaw # 转换为炮塔的局部Y轴角度(抵消坦克旋转的影响) target_local_yaw = wrapf(target_global_yaw - tank_global_yaw, -PI, PI) # 平滑过渡到目标角度 var current_local_yaw: float = wrapf(rotation.y, -PI, PI) rotation.y = lerp(current_local_yaw, target_local_yaw, smooth_speed * delta)
关键说明
- 用
global_rotation获取全局空间角度,彻底规避父节点旋转的干扰。 wrapf函数处理角度循环(-180°到180°转换),防止旋转出现跳变。- 通过
lerp实现平滑跟随,调整smooth_speed可控制跟随的响应速度。
额外注意
- 替换脚本中的
/root/Camera3D为你实际的相机节点路径。 - 若炮塔有初始旋转偏移,需在代码中加入对应偏移量修正。
内容的提问来源于stack exchange,提问作者Limer GG
相关产品推荐
相关产品推荐

