Click and Drag camera lagging behind

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By johnnywycliffe

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

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

pospathos | 2018-12-02 14:07

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?

pospathos | 2018-12-02 14:44

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

johnnywycliffe | 2018-12-02 18:14

:bust_in_silhouette: Reply From: pospathos

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

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

pospathos | 2018-12-02 20:18

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

johnnywycliffe | 2018-12-02 21:18

:bust_in_silhouette: Reply From: johnnywycliffe

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.

UPDATE:

I found out why it was so dodgy. When using get_global_camera_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.get_viewport().get_mouse_position() and now it tracks beautifully.

johnnywycliffe | 2018-12-23 21:33