Функциональность масштабирования колесика мыши на основе поворота камеры и вектора вперед

Я вполне доволен прогрессом, которого я добился до сих пор с моей 3D-камерой, но мне кажется, что в ней отсутствует функция увеличения / уменьшения масштаба с помощью колеса прокрутки.

Я уже некоторое время пытаюсь запрограммировать функцию cam_zoom () и не понимаю, как я могу ее реализовать.


Прежде чем я смогу реализовать функциональность 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,1,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,1,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,1,0),rot)
        player.rotate(Vector3(0,1,0),rot)
        cam.rotate(Vector3(0,1,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

[обновление] до сих пор не смог решить эту проблему! был бы признателен за любую помощь.


person Intro verb    schedule 20.10.2020    source источник


Ответы (1)


Для камеры вперед вы можете взять ось 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 не имеет смысла без коллизии. Просто установите преобразование.

person Theraot    schedule 26.10.2020
comment
Я запутался :/ - person Intro verb; 28.10.2020