Godot 4:如何实现基于相机视角的第三人称3D移动
问题分析与修复方案
你遇到的前后移动失效问题,核心原因是相机前向向量方向错误,以及部分逻辑的处理时机不合理。
问题根源
SpringArm3D默认局部Z轴朝向自身后方(相机挂载在SpringArm末端,实际前向是SpringArm的-Z方向)。你当前代码直接用camera.global_transform.basis.z作为前向,导致前后输入的方向完全错位,无法触发有效移动。
修复步骤
1. 修正相机前向向量
修改get_camera_relative_input函数,调整前向向量方向,并添加输入归一化避免斜向移动速度异常:
func get_camera_relative_input(input) -> Vector3: var cam_right = camera.global_transform.basis.x # 修正前向:SpringArm默认Z轴向后,取反得到相机实际前向 var cam_forward = -camera.global_transform.basis.z # 保持前向水平,消除坡度对移动方向的干扰 cam_forward = cam_forward.slide(Vector3.UP).normalized() # 生成相机相对输入向量,斜向移动时归一化避免速度叠加 var relative_input = cam_forward * input.y + cam_right * input.x return relative_input.normalized() if relative_input.length() > 1 else relative_input
2. 调整相机旋转的处理时机
相机旋转属于视觉更新逻辑,应放在_process而非_physics_process中,避免与物理帧冲突:
func _process(delta): ###Camera rotation code var camera_input = Input.get_vector("camera_left", "camera_right", "camera_up", "camera_down") var camera_x_move = camera_input.x * camera_speed * delta var camera_y_move = camera_input.y * camera_speed * delta if camera_input != Vector2.ZERO: camera.rotate_y(deg_to_rad(-camera_x_move) * controller_sensitivity) camera.rotate_x(deg_to_rad(-camera_y_move) * controller_sensitivity) camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-40), deg_to_rad(-10)) camera.rotation.z = 0
3. 完善移动逻辑
在_physics_process中补充重力逻辑,确保移动与物理系统的正确交互:
func _physics_process(delta): # 应用重力 if not is_on_floor(): velocity.y -= gravity * delta var input = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") var relative_input = get_camera_relative_input(input) var dir = Vector3(relative_input.x, 0, relative_input.z) # 应用移动速度 velocity.x = dir.x * move_speed velocity.z = dir.z * move_speed move_and_slide()
额外优化(可选)
如果需要角色朝向移动方向,可在move_and_slide()后添加:
if dir.length() > 0: model.look_at(global_position + dir, Vector3.UP)
内容的提问来源于stack exchange,提问作者b0sc007
相关产品推荐
相关产品推荐

