48 lines
1.4 KiB
GDScript3
48 lines
1.4 KiB
GDScript3
|
|
extends Camera2D
|
||
|
|
|
||
|
|
@export var move_speed = 3 # camera position lerp speed
|
||
|
|
@export var zoom_speed = 3 # camera zoom lerp speed for zooming in
|
||
|
|
@export var min_zoom = 5 # camera won't zoom closer than this
|
||
|
|
@export var max_zoom = 1 # camera won't zoom farther than this
|
||
|
|
@export var margin = Vector2(400, 200) # include some buffer area around targets
|
||
|
|
|
||
|
|
var targets = []
|
||
|
|
|
||
|
|
@onready var screen_size = get_viewport_rect().size
|
||
|
|
|
||
|
|
func _process(delta):
|
||
|
|
if !targets:
|
||
|
|
return
|
||
|
|
|
||
|
|
# Keep the camera centered among all targets
|
||
|
|
var p = Vector2.ZERO
|
||
|
|
for target in targets:
|
||
|
|
p += target.position
|
||
|
|
p /= targets.size()
|
||
|
|
position = lerp(position, p, move_speed * delta)
|
||
|
|
|
||
|
|
# Find the zoom that will contain all targets
|
||
|
|
var r = Rect2(position, Vector2.ONE)
|
||
|
|
for target in targets:
|
||
|
|
r = r.expand(target.position)
|
||
|
|
r = r.grow_individual(margin.x, margin.y, margin.x, margin.y)
|
||
|
|
var z
|
||
|
|
if r.size.x > r.size.y * screen_size.aspect():
|
||
|
|
z = 1 / clamp(r.size.x / screen_size.x, max_zoom, min_zoom)
|
||
|
|
else:
|
||
|
|
z = 1 / clamp(r.size.y / screen_size.y, max_zoom, min_zoom)
|
||
|
|
|
||
|
|
# Apply zoom instantly if zooming out, or lerp if zooming in
|
||
|
|
#if z < zoom.x: # Zooming in (smaller zoom level)
|
||
|
|
zoom = lerp(zoom, Vector2.ONE * z, zoom_speed * delta)
|
||
|
|
#else: # Zooming out (larger zoom level)
|
||
|
|
#zoom = Vector2.ONE * z
|
||
|
|
|
||
|
|
func add_target(t):
|
||
|
|
if not t in targets:
|
||
|
|
targets.append(t)
|
||
|
|
|
||
|
|
func remove_target(t):
|
||
|
|
if t in targets:
|
||
|
|
targets.erase(t)
|