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

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 (380 points)
edited

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)
``````