From 26b30eb032dfac964306aca55b84e1bede74c9ee Mon Sep 17 00:00:00 2001 From: RedisTKey Date: Tue, 13 Jan 2026 10:32:36 +0800 Subject: [PATCH] camera follower tool designing.... --- _camera/PlateformerCamera.tscn | 2 - addons/reedcamera/scripts/CameraPointer.gd | 19 +++++ .../camera_tools/CameraFollowController.gd | 84 +++++++++++++++++++ .../CameraFollowController.gd.uid | 1 + 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 addons/reedcamera/scripts/camera_tools/CameraFollowController.gd create mode 100644 addons/reedcamera/scripts/camera_tools/CameraFollowController.gd.uid diff --git a/_camera/PlateformerCamera.tscn b/_camera/PlateformerCamera.tscn index 935cd8e..e5ecf16 100644 --- a/_camera/PlateformerCamera.tscn +++ b/_camera/PlateformerCamera.tscn @@ -14,9 +14,7 @@ metadata/_custom_type_script = "uid://py4h5jxlncro" [node name="ReedCameraShakeController" type="Node" parent="CameraPointer"] script = ExtResource("2_rbequ") -affect_position = null affect_offset = true -affect_zoom = null metadata/_custom_type_script = "uid://dwr1s51svvank" [node name="ReedCameraAnchorController" type="Node" parent="CameraPointer"] diff --git a/addons/reedcamera/scripts/CameraPointer.gd b/addons/reedcamera/scripts/CameraPointer.gd index 68d7ef1..461ce50 100644 --- a/addons/reedcamera/scripts/CameraPointer.gd +++ b/addons/reedcamera/scripts/CameraPointer.gd @@ -164,5 +164,24 @@ func _emit_config_warning() -> void: _warned = true +## ========================= +## Public API +## ========================= +##获取相机 func get_camera() -> Camera2D: return _camera + +##获取特定工具 +func get_tool(tool_class: Script) -> Node: + for c in get_children(): + if c.get_script() == tool_class: + return c + return null + +##获取所有工具 +func get_tools() -> Array[CameraToolBasic]: + var out: Array[CameraToolBasic] = [] + for c in get_children(): + if c is CameraToolBasic: + out.append(c) + return out diff --git a/addons/reedcamera/scripts/camera_tools/CameraFollowController.gd b/addons/reedcamera/scripts/camera_tools/CameraFollowController.gd new file mode 100644 index 0000000..92eb39d --- /dev/null +++ b/addons/reedcamera/scripts/camera_tools/CameraFollowController.gd @@ -0,0 +1,84 @@ +extends CameraToolBasic +class_name ReedCameraFollowController + +const _CONSTANTS := preload("res://addons/reedcamera/_data/CameraSystemConst.gd") + +@export_group("Dead Zone") +@export var dead_zone_ratio := Rect2( + Vector2.ZERO, # 屏幕中心 + Vector2(0.4, 0.4) # 宽高(屏幕比例) +) + +@export_group("Follow") +@export var enabled_follow: bool = true +@export var follow_lerp := 0.12 # 0~1,越大越“跟手”,越小越“蔚蓝感”的滞后 + +var _follow_node2d : Node2D = null +var _desired_pos := Vector2.ZERO +var _camera: Camera2D = null + +func _update_follow(delta: float) -> void: + if not enabled_follow: + return + + if not _follow_node2d: + return + + var cam := _get_camera_from_pointer() + if not cam: + return + + # 初始化 + if not _initialized: + _pos = cam.global_position + _desired_pos = _pos + _initialized = true + + var view_rect := _get_camera_view_rect(cam) + var dead_rect := _get_dead_zone_world_rect(view_rect) + + var p := player.global_position + var delta_move := Vector2.ZERO + + if p.x < dead_rect.position.x: + delta_move.x = p.x - dead_rect.position.x + elif p.x > dead_rect.position.x + dead_rect.size.x: + delta_move.x = p.x - (dead_rect.position.x + dead_rect.size.x) + + if p.y < dead_rect.position.y: + delta_move.y = p.y - dead_rect.position.y + elif p.y > dead_rect.position.y + dead_rect.size.y: + delta_move.y = p.y - (dead_rect.position.y + dead_rect.size.y) + + if delta_move != Vector2.ZERO: + _desired_pos += delta_move + + # 可选 room clamp + if use_room_clamp: + _desired_pos = _desired_pos.clamp( + room_world_rect.position, + room_world_rect.position + room_world_rect.size + ) + + # 蔚蓝感:滞后 lerp + _pos = _pos.lerp(_desired_pos, follow_lerp) + +func _get_camera_from_pointer() -> Camera2D: + if _camera: + return _camera + + var p := get_parent() + if p and p.has_method("get_camera"): + _camera = p.get_camera() as Camera2D + return _camera + + return _camera + +func _get_camera_view_rect(cam: Camera2D) -> Rect2: + var screen_size := cam.get_viewport_rect().size + var zoom := cam.zoom + zoom.x = maxf(zoom.x, 0.001) + zoom.y = maxf(zoom.y, 0.001) + + var size := screen_size / zoom + return Rect2(cam.global_position - size * 0.5, size) diff --git a/addons/reedcamera/scripts/camera_tools/CameraFollowController.gd.uid b/addons/reedcamera/scripts/camera_tools/CameraFollowController.gd.uid new file mode 100644 index 0000000..f27968d --- /dev/null +++ b/addons/reedcamera/scripts/camera_tools/CameraFollowController.gd.uid @@ -0,0 +1 @@ +uid://wl83yn33gu3m