The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

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
in Engine by (24 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.

by (24 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
by (244 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 Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.