0 votes

I am trying to make a camera that you can drag around to pan around an area. In my current implementation, the movement is very choppy and not very accurate or responsive.

The _input(event) is used to start and stop the drag, and the _process(delta) is supposed to keep track of the mouse movement on a frame-by-frame basis.

Any help is appreciated.

extends Node2D

var LastMouseCoords = get_global_mouse_position()
var CurrentMouseCoords = LastMouseCoords
var dragState = false
onready var cam = get_node("Camera2D")

func _process(delta):
    CurrentMouseCoords = get_global_mouse_position()
    if dragState:
        var diff = LastMouseCoords - CurrentMouseCoords
        cam.translate(diff)
    LastMouseCoords = CurrentMouseCoords

func _input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT:
    if not dragState:
        dragState = true
    else:
        dragState = false
asked Dec 2, 2018 in Engine by johnnywycliffe (23 points)

Try to interpolate camera position between LastMouseCoords and CurrentMouseCoords instead of translating it by difference between those two.

I just tried your code and if I set Camera2D's Anchor Mode to DragCenter it seems to work ok, but if I set it to FixedTopLeft everything is a mess. Could it be a bug?

Lerping sends me off into the distance too rapidly to be useful. The below code was the closest is came to working.

var target = LastMouseCoords.linear_interpolate(CurrentMouseCoords, 0.5)
cam.position = target

2 Answers

0 votes
Best answer

I found a solution to the problem.

Camera smoothing actually seems to do it's job properly, making the camera less janky. Pair that with making the margins 0 from 0.2, and now the camera seems to move in a reasonable fashion. It's still slower than I'd like, but I can add a speed multiplier.

answered Dec 2, 2018 by johnnywycliffe (23 points)

UPDATE:

I found out why it was so dodgy. When using getglobalcamera_position(), it always saves the last position of the mouse to what it is now, and that includes how much it just shifted, causing it to jump back and forth each frame.

I switched to cam.getviewport().getmouse_position() and now it tracks beautifully.

+1 vote

This seems to work good:

extends Node2D

var LastMouseCoords = get_global_mouse_position()
var CurrentMouseCoords = LastMouseCoords
var dragState = false
onready var cam = get_node("Camera2D")

func _process(delta):
    if dragState:
        CurrentMouseCoords = get_global_mouse_position()
        var diff = ( LastMouseCoords - CurrentMouseCoords ).normalized()
        cam.translate(diff)
        LastMouseCoords = CurrentMouseCoords

func _input(event):
    if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT:
        if not dragState:
            dragState = true
        else:
            dragState = false
answered Dec 2, 2018 by pospathos (236 points)

you can add variable camSpeed and set it to some low value 1.2 or something like that, and than multiply diff with camSpeed: var diff = ( LastMouseCoords - CurrentMouseCoords ).normalized() * camSpeed

Interesting. If I copy your code to a new file, it works, but in my project, it all stops moving.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.