0 votes

Smoothly move the camera to the mouse, but so that the player is always visible on the screen and does not interfere with the function of turning the camera to the mouse and vice versa so that the function of turning the player to the mouse does not interfere with the first function

Godot version 3.2.3.stable.official
in Engine by (106 points)

1 Answer

+1 vote

Basically you want the camera to follow the mouse cursor while also making sure to keep the player on screen?

If we look at this line segment a-b, where (a) is the player and (b) is the cursor

--------a--------------------------------------------------------------b--------
< x----------------------Camera bounds----------------------------x>

As you can see, if we move the camera towards the right, point b(cursor),
Point a(player) will be off screen.

-----------------------------------------------------------b--------
< x----------------------Camera bounds----------------------------x>

Which means, to make sure that both point a and b are in the camera screen, we have to point the camera direction towards somewhere in the middle of point (a) and (b).

--------a-----------------------------x-------------------------------b--------
< x----------------------Camera bounds----------------------------x>

which can be expressed with the following code:

Camera2D.gd:

var interpolate_val = 1
func _physics_process(delta);
    var target = player.global_position 
    var mid_x = (target.x + get_global_mouse_position.x) / 2
    var mid_y = (target.y + get_global_mouse_position.y) / 2

    global_position = global_position.linear_interpolate(Vector2(mid_x,mid_y), interpolate_val * delta) 

The interpolate_val variable determines how fast the camera moves towards the targeted location, in this case the middle location between the cursor and player.

Incase your wondering, how does the math work, assuming point a=3, and point b=6

a(3) + b(6) = 9/2 = 4.5

if we look at a plot of points: 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0
we can confirm that 4.5 is indeed the middle of the two points. The code should also work the same for negative values or combination of both:

a(-3) + (-6) = -9 / 2 = -4.5
a(-2) + b(2) = 0 /2 = 0

And since the camera is always directed between the middle of the two points, point a and point b will always be within camera view.

by (332 points)
edited by

thanks, but I already found such a solution

const MAX_CAMERA_DISTANCE := 50.0
const MAX_CAMERA_PERCENT := 0.1
const CAMERA_SPEED := 0.1


export (NodePath) onready var player = get_node(player)
export (NodePath) onready var camera = get_node(camera)


func _process(_delta: float) -> void:
    var viewport := get_viewport()
    var viewport_center := viewport.size / 2.0
    var direction := viewport.get_mouse_position() - viewport_center
    var percent := (direction / viewport.size * 2.0).length()

    var camera_position: Vector2
    if percent < MAX_CAMERA_PERCENT:
        camera_position = player.global_position + direction.normalized() * MAX_CAMERA_DISTANCE * (percent / MAX_CAMERA_PERCENT)
    else:
        camera_position = player.global_position + direction.normalized() * MAX_CAMERA_DISTANCE

    camera.global_position = lerp(camera.global_position, camera_position, CAMERA_SPEED)
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.
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 webmaster@godotengine.org with your username.

Categories