extends Camera3D @export var height: float = 18.0 @export var horizontal_distance: float = 18.0 @export var horizontal_angle_deg: float = 45.0 @export var ortho_size: float = 15.0 @export var ortho_size_max: float = 40.0 const _FLASH_DURATION: float = 0.30 var _shake_amount: float = 0.0 var _shake_decay: float = 0.0 var _flash_timer: float = 0.0 var _flash_rect: ColorRect = null var _target_size: float = 0.0 func _ready() -> void: set_as_top_level(true) projection = PROJECTION_ORTHOGONAL _target_size = ortho_size size = ortho_size _setup_flash() func _setup_flash() -> void: var canvas := CanvasLayer.new() canvas.layer = 20 add_child(canvas) _flash_rect = ColorRect.new() _flash_rect.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) _flash_rect.color = Color(1.0, 0.25, 0.2, 0.0) _flash_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE canvas.add_child(_flash_rect) func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("zoom_in"): _target_size = clamp(_target_size / 1.2, ortho_size, ortho_size_max) if event.is_action_pressed("zoom_out"): _target_size = clamp(_target_size * 1.2, ortho_size, ortho_size_max) func _process(delta: float) -> void: size = lerpf(size, _target_size, delta * 10.0) var angle_rad := deg_to_rad(horizontal_angle_deg) var offset := Vector3( sin(angle_rad) * horizontal_distance, height, cos(angle_rad) * horizontal_distance, ) var target := get_parent() as Node3D global_position = target.global_position + offset look_at(target.global_position, Vector3.UP) if _shake_amount > 0.005: global_position += Vector3( randf_range(-_shake_amount, _shake_amount), randf_range(-_shake_amount * 0.25, _shake_amount * 0.25), randf_range(-_shake_amount, _shake_amount), ) _shake_amount = move_toward(_shake_amount, 0.0, _shake_decay * delta) if _flash_timer > 0.0: _flash_timer = maxf(0.0, _flash_timer - delta) _flash_rect.color.a = (_flash_timer / _FLASH_DURATION) * 0.6 else: _flash_rect.color.a = 0.0 func trigger_hit(strength: float) -> void: _shake_amount = strength * 0.5 _shake_decay = _shake_amount / 0.4 _flash_timer = _FLASH_DURATION