基于相机旋转和前向矢量的鼠标滚轮缩放功能

问题描述

到目前为止,我对自己的3D相机所取得的进步感到非常满意,但是我感觉它缺少滚轮放大功能

一段时间以来,我一直在尝试编写 cam_zoom()函数,但我对如何实现它感到困惑。


在实现缩放功能之前,我需要考虑我先前存在的代码

当前可以使用多种方式来旋转相机并使用当前设置进行平移。

当播放器旋转时,摄像机将平移。可以使用WSAD或按住/拖动鼠标右键来执行。

player_rotate()

func player_rotate(delta,dir):
        #rot can be adjusted to make rotation faster
        var rot = deg2rad(dir*90)*delta 
        #Forward is changed every time turning happens. 
        forward=forward.rotated(Vector3(0,1,0),rot)
        player.rotate(Vector3(0,rot)

cam_rotate()

func cam_rotate(delta,dir):
        #rot can be adjusted to make rotation faster
        var rot = deg2rad(dir*90)*delta 
        #Forward is changed every time turning happens. 
        cam.rotate(Vector3(0,rot)

如果按下A

# IF A (no mouse)
if Input.is_action_pressed("move_left") and !Input.is_action_pressed("right_mouse") and !Input.is_action_pressed("left_mouse"):
    #cam_reset(delta)
    camlock.UNLOCKED
    player_rotate(delta,1)
    cam_rotate(delta,1)

cam_reset()

func cam_reset(delta):
    #return behind player if the camera is LOCKED
    
        target_location = player.translation
        target_rotation = player.rotation 
        rotation_lerp = 0.0
        rotation_speed = 8.0
        
        if rotation_lerp < 1:
            rotation_lerp += delta * rotation_speed
        elif rotation_lerp > 1:
            rotation_lerp = 1
        cam.transform.basis = cam.transform.basis.slerp(target_rotation,rotation_lerp).orthonormalized()

按住鼠标左键时,相机可以围绕播放器自由旋转(带夹子)。

#if only left mouse is pressed
    if Input.is_action_pressed("left_mouse") and !Input.is_action_pressed("right_mouse"):
        print("left")
        state=movementstate.ONLYCAMERA
        backupMouse=lastmouse
        Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
        
    if state==movementstate.FULL:
        #last mouse will always contain the last position your mouse has moved to
        #we do this with _input
        #The world has to stay rotating even if the pointer would go out of bounds
        #that's why it's always reset to (500,500) < this should not be hardcoded btw but probably be 
        #half of the width/height of your current view
        var R=Vector2(500,500)-lastmouse#R contains the amount of pixels the mouse moved since last pass of _physics_process
        Input.warp_mouse_position(Vector2(500,500))
        
        #rot can be adjusted to make rotation faster
        var rot = deg2rad(R.x*90)*delta 
        #Forward is changed every time turning happens. 
        forward=forward.rotated(Vector3(0,rot)
        cam.rotate(Vector3(0,rot)

当前的问题是,实现的任何鼠标滚动功能都需要考虑鼠标左旋转。我觉得相机可能需要一个“前进”矢量,以便知道新的“前进”是POST旋转。

当前cam_zoom()

func cam_zoom(delta):
    if zoom_dir != 0:
        target_location = Vector3(cam.translation.x,cam.translation.y,cam.translation.z)
        cam.translation =  target_location + forward * 0.2 * zoom_dir
        
        
    zoom_dir = 0

以下是我正在工作的godot项目的链接 https://gofile.io/d/T9TAop

[更新]仍无法解决!将不胜感激。

解决方法

对于向前的摄像头,您可以将z轴作为摄像头变换的基础。

但是,我建议您以其他方式实施您的相机。在共享代码中,您有两个由鼠标控制的旋转轴:

cam.rotation_degrees.x -= event.relative.y * V_LOOK_SENS
cam.rotation_degrees.x = clamp(cam.rotation_degrees.x,-90,10)
cam.rotation_degrees.y -= event.relative.x * H_LOOK_SENS

除了旋转以外,放置相机还需要了解什么?好吧,它应该看着头像,并且应该在一定距离之外。

因此进行身份转换,将其沿z轴平移距离,然后根据所需的相机旋转对其进行旋转,然后将化身的变换与其相乘。它应该为您提供相机的变换。

我不知道您为什么将相机变成运动机体。 move_and_slide没有冲突就没有意义。只需设置转换即可。