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

Godot 4.1中Camera3D环绕CharacterBody3D的定位控制问题

Godot 3D相机问题:旋转时焦点偏移+相机异常前移

问题描述

刚接触Godot 3D开发,想要实现如下场景:

  • CharacterBody3D(下称焦点)始终处于屏幕中心
  • Camera3D固定在焦点的上方后方位置
  • 按Q/E键时,相机围绕焦点旋转,其余世界随之转动,焦点保持居中

但实际运行时出现两个问题:

  1. 按Q/E旋转时,焦点沿椭圆路径移动,无法保持屏幕中心
  2. 之前实现过居中旋转与WASD平移,但相机突然前移,导致焦点被截断一半,仅能看到焦点前方(屏幕上半部分)的行星

相关代码位于res://camera/CameraFocus.gd,修改后的关键代码片段如下:

func rotate_around_focus_character(delta):
# 围绕焦点角色旋转相机
var theta = deg_to_rad(rotation_speed * delta)
#var rotation_center = focus.global_transform.origin #+ Vector3(0, 10, 0)

if Input.is_action_pressed("rotate_left"):
    global_transform.origin = focus.global_transform.origin
    global_transform.basis = camera_3d.global_transform.basis.rotated(Vector3(0, 1, 0), theta)
    
if Input.is_action_pressed("rotate_right"):
    global_transform.origin = focus.global_transform.origin
    global_transform.basis = camera_3d.global_transform.basis.rotated(Vector3(0, 1, 0), -theta)
func track_focus_with_camera(delta):
if focus:
    var camera_3d_pos = camera_3d.global_transform.origin
    print("camera_3d_pos = " + str(camera_3d_pos))
    global_transform.origin = focus.global_transform.origin.lerp(camera_3d.position, 0.1)

问题根源与解决方案

1. 旋转逻辑错误

直接将相机原点绑定到焦点原点再旋转basis,会导致相机局部坐标系混乱,旋转路径偏离预期,出现椭圆偏移。正确做法是基于相机与焦点的偏移向量做旋转,再更新位置并让相机始终看向焦点。

修正后的旋转函数:

func rotate_around_focus_character(delta):
    var theta = deg_to_rad(rotation_speed * delta)
    # 计算相机相对于焦点的偏移向量
    var offset = global_transform.origin - focus.global_transform.origin
    
    if Input.is_action_pressed("rotate_left"):
        # 绕焦点的Y轴旋转偏移向量
        offset = offset.rotated(Vector3.UP, theta)
    if Input.is_action_pressed("rotate_right"):
        offset = offset.rotated(Vector3.UP, -theta)
    
    # 更新相机位置并保持看向焦点
    global_transform.origin = focus.global_transform.origin + offset
    look_at(focus.global_transform.origin, Vector3.UP)

2. 跟踪逻辑反向

原track_focus_with_camera函数的插值方向搞反了,导致相机异常前移。应该让相机从当前位置向焦点的目标偏移位置平滑插值。

修正后的跟踪函数(假设相机需要固定在焦点上方后方Vector3(0,5,-10)的位置,可按需调整):

func track_focus_with_camera(delta):
    if focus:
        # 定义相机相对于焦点的固定偏移
        var target_offset = Vector3(0, 5, -10)
        # 将偏移转换为全局坐标系下的目标位置
        var target_pos = focus.global_transform.origin + focus.global_transform.basis * target_offset
        # 平滑插值到目标位置
        global_transform.origin = global_transform.origin.lerp(target_pos, 0.1)
        # 始终看向焦点
        look_at(focus.global_transform.origin, Vector3.UP)

额外提示

  • 确保没有多个脚本同时修改相机的变换属性,避免逻辑冲突
  • 调整rotation_speed和插值系数(0.1)可以控制旋转速度和跟踪的平滑度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:15:24