Move camera to mouse

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

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

:bust_in_silhouette: Reply From: bloodsign

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.

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)

Timofey | 2021-02-20 11:07