[gd_scene load_steps=3 format=3 uid="uid://b8pv5wtbo0y20"] [ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="2_s84x6"] [sub_resource type="GDScript" id="GDScript_3tsvq"] script/source = "'''全局的相机管理器 ======= 外部调用函数 ======= ''' extends Node var _cached_player_camera: GlobalCamera var _cached_anchors: Array[CameraAnchor] = [] var _current_anchor: CameraAnchor var _switch_tween: Tween ## 玩家关卡内静态相机 const PLAYER_CAMERA_SCENE:= preload(\"res://_shared/camera/PlayerStaticCamera.tscn\") ## 注册玩家相机 func register_player_camera(owner: Node) -> GlobalCamera: if not _cached_player_camera: _cached_player_camera = PLAYER_CAMERA_SCENE.instantiate() as GlobalCamera if _cached_player_camera: owner.add_child(_cached_player_camera) return _cached_player_camera ## 外部获取玩家全局相机 func get_cached_camera() -> GlobalCamera: return _cached_player_camera ## 注册一个相机锚点 func register_anchor(anchor: CameraAnchor) -> void: if anchor in _cached_anchors: return _cached_anchors.append(anchor) _sort_anchors() _try_auto_switch() ## 注销一个相机锚点 func unregister_anchor(anchor: CameraAnchor) -> void: _cached_anchors.erase(anchor) if _current_anchor == anchor: _current_anchor = null _try_auto_switch() ## 排序已有的锚点 func _sort_anchors() -> void: _cached_anchors.sort_custom(func(a, b): return a.priority > b.priority ) ## 尝试自切换 func _try_auto_switch() -> void: for a in _cached_anchors: if a.enabled: switch_anchor(a) return ## 重置所有的Camera的priority func reset_all_camera_priority() -> void: for a in _cached_anchors: a.priority = 0 ## 切换相机 func switch_anchor(target_anchor: CameraAnchor) -> void: if target_anchor == null: return if target_anchor == _current_anchor: return if not is_instance_valid(_cached_player_camera): return # 中断旧 Tween if _switch_tween and _switch_tween.is_running(): _switch_tween.kill() _switch_tween = null var camera := _cached_player_camera var blend_time : float = max(target_anchor.blend_time, 0.001) # 创建 Tween(关键:ignore time scale) _switch_tween = get_tree().create_tween() _switch_tween.set_ignore_time_scale(true) _switch_tween.set_trans(Tween.TRANS_SINE) _switch_tween.set_ease(Tween.EASE_OUT) # ===== 位置 ===== _switch_tween.tween_property( camera, \"global_position\", target_anchor.global_position, blend_time ) # ===== Zoom ===== _switch_tween.tween_property( camera, \"zoom\", target_anchor.zoom, blend_time ) # ===== Offset ===== _switch_tween.tween_property( camera, \"offset\", target_anchor.offset, blend_time ) # 完成回调 _switch_tween.finished.connect(func(): _current_anchor = target_anchor ) _current_anchor = target_anchor " [node name="CameraSystem" type="Node"] script = SubResource("GDScript_3tsvq") [node name="Camera2D" type="Camera2D" parent="."] [node name="PhantomCameraHost" type="Node" parent="Camera2D"] process_priority = 300 process_physics_priority = 300 script = ExtResource("2_s84x6") metadata/_custom_type_script = "uid://bd046eokvcnu2"