相机功能beta版本

This commit is contained in:
Reed 2026-01-13 16:52:45 +08:00
parent 26b30eb032
commit b8373aed65
15 changed files with 369 additions and 58 deletions

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=5 format=3 uid="uid://cw6buluknvjj"] [gd_scene load_steps=6 format=3 uid="uid://cw6buluknvjj"]
[ext_resource type="Script" uid="uid://djk7tg2puphgv" path="res://_camera/camera_test.gd" id="1_05blt"] [ext_resource type="Script" uid="uid://djk7tg2puphgv" path="res://_camera/camera_test.gd" id="1_05blt"]
[ext_resource type="Script" uid="uid://py4h5jxlncro" path="res://addons/reedcamera/scripts/CameraPointer.gd" id="1_e7rkk"] [ext_resource type="Script" uid="uid://py4h5jxlncro" path="res://addons/reedcamera/scripts/CameraPointer.gd" id="1_e7rkk"]
[ext_resource type="Script" uid="uid://dwr1s51svvank" path="res://addons/reedcamera/scripts/camera_tools/CameraShakeController.gd" id="2_rbequ"] [ext_resource type="Script" uid="uid://dwr1s51svvank" path="res://addons/reedcamera/scripts/camera_tools/CameraShakeController.gd" id="2_rbequ"]
[ext_resource type="Script" uid="uid://bhl5it46hv4n2" path="res://addons/reedcamera/scripts/camera_tools/CameraAnchorController.gd" id="4_877nu"] [ext_resource type="Script" uid="uid://bhl5it46hv4n2" path="res://addons/reedcamera/scripts/camera_tools/CameraAnchorController.gd" id="4_877nu"]
[ext_resource type="Script" uid="uid://wl83yn33gu3m" path="res://addons/reedcamera/scripts/camera_tools/CameraFollowController.gd" id="5_kdnmf"]
[node name="PlateformerCamera" type="Camera2D"] [node name="PlateformerCamera" type="Camera2D"]
script = ExtResource("1_05blt") script = ExtResource("1_05blt")
@ -22,3 +23,8 @@ script = ExtResource("4_877nu")
affect_position = true affect_position = true
affect_zoom = true affect_zoom = true
metadata/_custom_type_script = "uid://bhl5it46hv4n2" metadata/_custom_type_script = "uid://bhl5it46hv4n2"
[node name="ReedCameraFollowController" type="Node" parent="CameraPointer"]
script = ExtResource("5_kdnmf")
affect_position = true
metadata/_custom_type_script = "uid://wl83yn33gu3m"

View File

@ -76,7 +76,6 @@ func _draw() -> void:
func _process(delta: float) -> void: func _process(delta: float) -> void:
queue_redraw() queue_redraw()
func set_move_input(dir: Vector2) -> void: func set_move_input(dir: Vector2) -> void:
m_input_intent_direction = dir m_input_intent_direction = dir

View File

@ -119,7 +119,6 @@ script = ExtResource("10_g4f48")
[node name="CameraAnchor" parent="Props" instance=ExtResource("11_o5yb1")] [node name="CameraAnchor" parent="Props" instance=ExtResource("11_o5yb1")]
position = Vector2(-39, 1203) position = Vector2(-39, 1203)
zoom = Vector2(0.75, 0.75)
[node name="[Prop_0000]" type="Node" parent="Props/CameraAnchor"] [node name="[Prop_0000]" type="Node" parent="Props/CameraAnchor"]
script = ExtResource("12_vhd7q") script = ExtResource("12_vhd7q")

View File

@ -134,8 +134,7 @@ init_act_id = 0
script = ExtResource("7_8ou3l") script = ExtResource("7_8ou3l")
[node name="CameraAnchor" parent="Props" instance=ExtResource("8_dq7pn")] [node name="CameraAnchor" parent="Props" instance=ExtResource("8_dq7pn")]
position = Vector2(540, -400) position = Vector2(336, -385)
zoom = Vector2(0.75, 0.75)
limit_top = -335 limit_top = -335
limit_bottom = 240 limit_bottom = 240
limit_left = -427 limit_left = -427
@ -159,10 +158,10 @@ state_id = 1
effects = Array[ExtResource("12_fmhh5")]([ExtResource("14_nnp13")]) effects = Array[ExtResource("12_fmhh5")]([ExtResource("14_nnp13")])
[node name="PlayerTriggerVolumn" parent="Props" instance=ExtResource("15_lg3ok")] [node name="PlayerTriggerVolumn" parent="Props" instance=ExtResource("15_lg3ok")]
visible = false
position = Vector2(560, -480) position = Vector2(560, -480)
[node name="CollisionShape2D" type="CollisionShape2D" parent="Props/PlayerTriggerVolumn"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Props/PlayerTriggerVolumn"]
visible = false
show_behind_parent = true show_behind_parent = true
position = Vector2(-25.5, -2) position = Vector2(-25.5, -2)
shape = SubResource("RectangleShape2D_oupin") shape = SubResource("RectangleShape2D_oupin")

View File

@ -1,4 +1,4 @@
[gd_resource type="Resource" script_class="SceneTrigger" load_steps=16 format=3 uid="uid://bym4pb0ellj7b"] [gd_resource type="Resource" script_class="SceneTrigger" load_steps=20 format=3 uid="uid://bym4pb0ellj7b"]
[ext_resource type="Script" uid="uid://baamspwt4rm4r" path="res://addons/reedscene/scene/guard.gd" id="1_ebfhi"] [ext_resource type="Script" uid="uid://baamspwt4rm4r" path="res://addons/reedscene/scene/guard.gd" id="1_ebfhi"]
[ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/scene_trigger/base/SceneTrigger.gd" id="2_cq8o1"] [ext_resource type="Script" uid="uid://ons77en82uls" path="res://addons/reedscene/scene/scene_trigger/base/SceneTrigger.gd" id="2_cq8o1"]
@ -7,6 +7,7 @@
[ext_resource type="Script" uid="uid://bjstkg23cq6vq" path="res://addons/reedscene/scene/scene_trigger/STE_SwitchAct.gd" id="5_m44nk"] [ext_resource type="Script" uid="uid://bjstkg23cq6vq" path="res://addons/reedscene/scene/scene_trigger/STE_SwitchAct.gd" id="5_m44nk"]
[ext_resource type="Script" uid="uid://c8qq8400vebpg" path="res://addons/reedscene/scene/scene_trigger/STT_Self.gd" id="6_qb8kc"] [ext_resource type="Script" uid="uid://c8qq8400vebpg" path="res://addons/reedscene/scene/scene_trigger/STT_Self.gd" id="6_qb8kc"]
[ext_resource type="Script" uid="uid://dcn3k2vc6on0c" path="res://addons/reedscene/scene/scene_trigger/STT_Tree.gd" id="7_547il"] [ext_resource type="Script" uid="uid://dcn3k2vc6on0c" path="res://addons/reedscene/scene/scene_trigger/STT_Tree.gd" id="7_547il"]
[ext_resource type="Script" uid="uid://cwxwsfl1mx7kc" path="res://addons/reedscene/scene/scene_trigger/STT_Autoload.gd" id="8_cq8o1"]
[ext_resource type="Script" uid="uid://cdprpen0jyr6d" path="res://addons/reedscene/scene/scene_trigger/STR_NodePath.gd" id="8_kur88"] [ext_resource type="Script" uid="uid://cdprpen0jyr6d" path="res://addons/reedscene/scene/scene_trigger/STR_NodePath.gd" id="8_kur88"]
[sub_resource type="Resource" id="Resource_yc616"] [sub_resource type="Resource" id="Resource_yc616"]
@ -41,6 +42,22 @@ target = SubResource("Resource_kdh4c")
effect = Array[ExtResource("4_g7ixm")]([SubResource("Resource_jd40h")]) effect = Array[ExtResource("4_g7ixm")]([SubResource("Resource_jd40h")])
metadata/_custom_type_script = "uid://dxj5vimigc651" metadata/_custom_type_script = "uid://dxj5vimigc651"
[sub_resource type="Resource" id="Resource_cq8o1"]
script = ExtResource("5_m44nk")
func_name = &"player_follow_camera"
metadata/_custom_type_script = "uid://bjstkg23cq6vq"
[sub_resource type="Resource" id="Resource_m0qh3"]
script = ExtResource("8_cq8o1")
autoload_name = &"GlobalEvent"
metadata/_custom_type_script = "uid://cwxwsfl1mx7kc"
[sub_resource type="Resource" id="Resource_g7ixm"]
script = ExtResource("3_m0qh3")
target = SubResource("Resource_m0qh3")
effect = Array[ExtResource("4_g7ixm")]([SubResource("Resource_cq8o1")])
metadata/_custom_type_script = "uid://dxj5vimigc651"
[sub_resource type="Resource" id="Resource_8u4ru"] [sub_resource type="Resource" id="Resource_8u4ru"]
script = ExtResource("8_kur88") script = ExtResource("8_kur88")
node_path = NodePath("../Props/PlayerTriggerVolumn") node_path = NodePath("../Props/PlayerTriggerVolumn")
@ -50,5 +67,5 @@ metadata/_custom_type_script = "uid://cdprpen0jyr6d"
[resource] [resource]
script = ExtResource("2_cq8o1") script = ExtResource("2_cq8o1")
trigger_register_conifg = SubResource("Resource_8u4ru") trigger_register_conifg = SubResource("Resource_8u4ru")
trigger_effect_pairs = Array[ExtResource("3_m0qh3")]([SubResource("Resource_vv5v7"), SubResource("Resource_ig5jt")]) trigger_effect_pairs = Array[ExtResource("3_m0qh3")]([SubResource("Resource_vv5v7"), SubResource("Resource_ig5jt"), SubResource("Resource_g7ixm")])
metadata/_custom_type_script = "uid://ons77en82uls" metadata/_custom_type_script = "uid://ons77en82uls"

View File

@ -6,6 +6,8 @@ signal player_dead(player: Player)
var _cached_player_controller: PlayerController var _cached_player_controller: PlayerController
var _cached_player: Player var _cached_player: Player
var _camera_follower : Node = null
## player controller進入tree會注冊自己到Global ## player controller進入tree會注冊自己到Global
func register_player_controller(pc: PlayerController) -> PlayerController: func register_player_controller(pc: PlayerController) -> PlayerController:
if not pc: return null if not pc: return null
@ -18,6 +20,10 @@ func register_player(player: Player) -> Player:
if not player: return null if not player: return null
_cached_player = player _cached_player = player
##如果我们缓存了一个camera_follower,在玩家重生的时候我们会让follower自动绑定
if _camera_follower:
_camera_follower.register_follower(_cached_player)
return _cached_player return _cached_player
## 外部快速获取Player ## 外部快速获取Player
@ -28,6 +34,28 @@ func get_player() -> Player:
func get_player_controller() -> PlayerController: func get_player_controller() -> PlayerController:
return _cached_player_controller return _cached_player_controller
func player_follow_camera() -> void:
if not _cached_player:return
var cam := ReedCameraSystem.get_current_camera_pointer() as CameraPointer
if not cam:return
var follower := cam.get_tool_by_type(CameraPointer.ToolType.FOLLOWER)
if not follower:return
follower.register_follower(_cached_player)
_camera_follower = follower
func player_unfollow_camera() -> void:
var cam := ReedCameraSystem.get_current_camera_pointer() as CameraPointer
if not cam:return
var follower := cam.get_tool_by_type(CameraPointer.ToolType.FOLLOWER)
if not follower:return
follower.unregister_follower()
_camera_follower = null
## 外部用于监听Player死亡 ## 外部用于监听Player死亡
func boradcast_player_dead_event(player:Player) -> void: func boradcast_player_dead_event(player:Player) -> void:
player_dead.emit(player) player_dead.emit(player)

View File

@ -7,6 +7,10 @@ const CAMERA_SYSTEM_NAME : StringName = "ReedCameraSystem"
const CAMERA_ANCHOR_NAME : StringName = "CameraAnchor" const CAMERA_ANCHOR_NAME : StringName = "CameraAnchor"
const CAMERA_FOLLOWER_NAME : StringName = "CameraFollower" const CAMERA_FOLLOWER_NAME : StringName = "CameraFollower"
const CAMERA_TOOL_SHAKER : String = "res://addons/reedcamera/scripts/camera_tools/CameraShakeController.gd"
const CAMERA_TOOL_ANCHOR : String = "res://addons/reedcamera/scripts/camera_tools/CameraAnchorController.gd"
const CAMERA_TOOL_FOLLOWER : String = "res://addons/reedcamera/scripts/camera_tools/CameraFollowController.gd"
#endregion #endregion
#region GroupName #region GroupName

View File

@ -4,6 +4,20 @@ class_name CameraPointer
const _CONSTANTS := preload("res://addons/reedcamera/_data/CameraSystemConst.gd") const _CONSTANTS := preload("res://addons/reedcamera/_data/CameraSystemConst.gd")
## 相机指针所能持有的工具种类
enum ToolType{
SHAKER,
ANCHOR,
FOLLOWER
}
## 相机工具和脚本的映射
const type_script_map:Dictionary = {
ToolType.SHAKER : preload("res://addons/reedcamera/scripts/camera_tools/CameraShakeController.gd"),
ToolType.ANCHOR : preload("res://addons/reedcamera/scripts/camera_tools/CameraAnchorController.gd"),
ToolType.FOLLOWER : preload("res://addons/reedcamera/scripts/camera_tools/CameraFollowController.gd")
}
var _camera: Camera2D var _camera: Camera2D
var _editor_valid := false var _editor_valid := false
var _runtime_registered := false var _runtime_registered := false
@ -17,6 +31,7 @@ var _pos_dirty := false
var _offset_dirty := false var _offset_dirty := false
var _zoom_dirty := false var _zoom_dirty := false
func _enter_tree() -> void: func _enter_tree() -> void:
if Engine.is_editor_hint(): if Engine.is_editor_hint():
call_deferred("_editor_verify") call_deferred("_editor_verify")
@ -123,9 +138,8 @@ func _ready() -> void:
if Engine.is_editor_hint(): if Engine.is_editor_hint():
return return
_camera = _find_camera()
if not _camera: if not _camera:
return _camera = _find_camera()
_request_register() _request_register()
@ -169,6 +183,8 @@ func _emit_config_warning() -> void:
## ========================= ## =========================
##获取相机 ##获取相机
func get_camera() -> Camera2D: func get_camera() -> Camera2D:
if not _camera:
_camera = _find_camera()
return _camera return _camera
##获取特定工具 ##获取特定工具
@ -178,6 +194,10 @@ func get_tool(tool_class: Script) -> Node:
return c return c
return null return null
##通过类型返回工具
func get_tool_by_type(type:ToolType) -> Node:
return get_tool(type_script_map.get(type))
##获取所有工具 ##获取所有工具
func get_tools() -> Array[CameraToolBasic]: func get_tools() -> Array[CameraToolBasic]:
var out: Array[CameraToolBasic] = [] var out: Array[CameraToolBasic] = []

View File

@ -0,0 +1,114 @@
@tool
extends Node2D
class_name ScreenRatioRect
# ===============================
# Internal State
# ===============================
var _rect: Rect2 = Rect2()
var _line_color: Color = Color(0.2, 0.9, 0.4, 0.9)
var _line_width: float = 2.0
var _target_node: Node2D = null
var _target_screen_pos: Vector2 = Vector2.ZERO
var _target_radius: float = 6.0
var _target_color: Color = Color(1, 0.3, 0.3, 0.9)
func _process(_delta: float) -> void:
if Engine.is_editor_hint():
return
if _target_node:
_update_target_screen_pos()
queue_redraw()
# ===============================
# Public API
# ===============================
## 通过屏幕比例设置0~1
func set_ratio(ratio: Vector2) -> void:
var viewport_size := get_viewport_rect().size
var size := viewport_size * ratio
var pos := (viewport_size - size) * 0.5
set_rect(Rect2(pos, size))
## 直接设置屏幕空间 Rect
func set_rect(rect: Rect2) -> void:
_rect = rect
queue_redraw()
## 设置绘制风格
func set_style(color: Color, width: float = 2.0) -> void:
_line_color = color
_line_width = width
queue_redraw()
## 设置追踪点
func set_target_node(node: Node2D) -> void:
_target_node = node
_update_target_screen_pos()
queue_redraw()
## 更新targetnode在屏幕的位置
func _update_target_screen_pos() -> void:
if not _target_node:
return
_target_screen_pos = \
_target_node.get_global_transform_with_canvas().get_origin()
## 可选:快速隐藏 / 显示
func clear() -> void:
_target_node = null
_rect = Rect2()
queue_redraw()
# ===============================
# Draw
# ===============================
func _draw() -> void:
if _rect.size == Vector2.ZERO:
return
var left := _rect.position.x
var right := _rect.position.x + _rect.size.x
var top := _rect.position.y
var bottom := _rect.position.y + _rect.size.y
var vp_size := get_viewport_rect().size
# 上边线
draw_line(
Vector2(0, top),
Vector2(vp_size.x, top),
_line_color,
_line_width
)
# 下边线
draw_line(
Vector2(0, bottom),
Vector2(vp_size.x, bottom),
_line_color,
_line_width
)
# 左边线
draw_line(
Vector2(left, 0),
Vector2(left, vp_size.y),
_line_color,
_line_width
)
# 右边线
draw_line(
Vector2(right, 0),
Vector2(right, vp_size.y),
_line_color,
_line_width
)
##绘制角色位置锚点
if _target_node:
draw_circle(_target_screen_pos, _target_radius, _target_color)

View File

@ -0,0 +1 @@
uid://dckyyfvj25bxf

View File

@ -2,25 +2,82 @@ extends CameraToolBasic
class_name ReedCameraFollowController class_name ReedCameraFollowController
const _CONSTANTS := preload("res://addons/reedcamera/_data/CameraSystemConst.gd") const _CONSTANTS := preload("res://addons/reedcamera/_data/CameraSystemConst.gd")
const _DEBUG_TOOL := preload("res://addons/reedcamera/scripts/camera_tools/DeadZoneDebug.tscn")
@export_group("Dead Zone") @export_group("Dead Zone")
@export var dead_zone_ratio := Rect2( @export var dead_zone_ratio : Vector2 = Vector2(.6,.6)
Vector2.ZERO, # 屏幕中心
Vector2(0.4, 0.4) # 宽高(屏幕比例)
)
@export_group("Follow") @export_group("Follow")
@export var enabled_follow: bool = true @export var enabled_follow: bool = true
@export var follow_speed: float = 600.0 # 世界单位 / 秒
@export var follow_lerp := 0.12 # 0~1越大越“跟手”越小越“蔚蓝感”的滞后 @export var follow_lerp := 0.12 # 0~1越大越“跟手”越小越“蔚蓝感”的滞后
##TODO:后续添加一下Runtime的修改逻辑
@export_group("Debug")
@export var show_preview: bool = true
var _show_preview: bool = false:
set(value):
_update_debug(value)
_show_preview = value
@export var preview_color: Color = Color.AQUAMARINE
@export var preview_line_width : float = 2.0
enum State{
IDLE,
CHASING,
STATIC
}
## 用于描述和切换follower工具的状态
var _current_state: State = State.IDLE
##Follower工具绑定的followNode
var _follow_node2d : Node2D = null var _follow_node2d : Node2D = null
var _desired_pos := Vector2.ZERO ##最终的位置
var _final_position: Vector2
##缓存全局系统
var _sys: Object = null
##缓存DebugTool
var _screen_ratio_rect_draw_tool: Node = null
##缓存camera
var _camera: Camera2D = null var _camera: Camera2D = null
func _update_follow(delta: float) -> void: func _ready() -> void:
_show_preview = show_preview
func _process(delta: float) -> void:
#print(_current_state)
if _current_state == State.IDLE:
return
if _current_state == State.CHASING or State.STATIC:
update_follow(delta)
func _update_debug(debug:bool) -> void:
if debug:
if _screen_ratio_rect_draw_tool:
var t := _screen_ratio_rect_draw_tool.get_child(0)
t.set_ratio(dead_zone_ratio)
t.set_target_node(_follow_node2d)
t.set_style(preview_color,preview_line_width)
return
else:
var t := _DEBUG_TOOL.instantiate()
self.add_child(t)
_screen_ratio_rect_draw_tool = t
t.get_child(0).set_ratio(dead_zone_ratio)
t.get_child(0).set_target_node(_follow_node2d)
t.get_child(0).set_style(preview_color,preview_line_width)
else:
if not _screen_ratio_rect_draw_tool:
return
else:
_screen_ratio_rect_draw_tool.get_child(0).clear()
func update_follow(delta: float) -> void:
if not enabled_follow: if not enabled_follow:
return return
if not _follow_node2d: if not _follow_node2d:
return return
@ -28,41 +85,64 @@ func _update_follow(delta: float) -> void:
if not cam: if not cam:
return return
# 初始化 # 0. 读取相机的全局坐标
if not _initialized: _final_position = cam.global_position
_pos = cam.global_position
_desired_pos = _pos
_initialized = true
var view_rect := _get_camera_view_rect(cam) # 1. target 的屏幕坐标Canvas Space
var dead_rect := _get_dead_zone_world_rect(view_rect) var t_in_screen :Vector2 = \
_follow_node2d.get_global_transform_with_canvas().get_origin()
var p := player.global_position var screen_size : Vector2 = _get_camera_system().get_screen_size()
var delta_move := Vector2.ZERO var screen_center : Vector2 = screen_size * 0.5
var dead_half : Vector2 = screen_size * dead_zone_ratio * 0.5
if p.x < dead_rect.position.x: # 2. 获得移动方向
delta_move.x = p.x - dead_rect.position.x var offset := \
elif p.x > dead_rect.position.x + dead_rect.size.x: _compute_deadzone_offset(
delta_move.x = p.x - (dead_rect.position.x + dead_rect.size.x) t_in_screen,
screen_center,
if p.y < dead_rect.position.y: dead_half
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 if offset == Vector2.ZERO:
_pos = _pos.lerp(_desired_pos, follow_lerp) _current_state = State.STATIC
return
_current_state = State.CHASING
var move_dir := offset.normalized()
var world_velocity := (move_dir * follow_speed) / cam.zoom
##如果存在move_dir则我们认为相机需要chasing player
var desired_pos := _final_position + world_velocity * delta
if follow_lerp > 0.0:
_final_position = cam.global_position.lerp(desired_pos, follow_lerp)
else:
_final_position = desired_pos
func _compute_deadzone_offset(
screen_pos: Vector2,
screen_center: Vector2,
dead_half: Vector2
) -> Vector2:
var o := Vector2.ZERO
var dx := screen_pos.x - screen_center.x
var dy := screen_pos.y - screen_center.y
if dx < -dead_half.x:
o.x = dx + dead_half.x
elif dx > dead_half.x:
o.x = dx - dead_half.x
if dy < -dead_half.y:
o.y = dy + dead_half.y
elif dy > dead_half.y:
o.y = dy - dead_half.y
return o
## 从相机指针获取相机组件
func _get_camera_from_pointer() -> Camera2D: func _get_camera_from_pointer() -> Camera2D:
if _camera: if _camera:
return _camera return _camera
@ -74,11 +154,38 @@ func _get_camera_from_pointer() -> Camera2D:
return _camera return _camera
func _get_camera_view_rect(cam: Camera2D) -> Rect2: ## 获取全局相机管理器
var screen_size := cam.get_viewport_rect().size func _get_camera_system() -> Object:
var zoom := cam.zoom if _sys:
zoom.x = maxf(zoom.x, 0.001) return _sys
zoom.y = maxf(zoom.y, 0.001)
var size := screen_size / zoom if Engine.has_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME):
return Rect2(cam.global_position - size * 0.5, size) _sys = Engine.get_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME)
return _sys
##外部调用,设置一个相机系统的跟随者
func register_follower(follower: Node2D) -> void:
_follow_node2d = follower
if self._current_state == State.IDLE:
start_follow()
##外部调用,移除一共相机系统的跟随者
func unregister_follower() -> void:
_follow_node2d = null
stop_follow()
##外部调用,开始跟随
func start_follow() -> void:
_current_state = State.STATIC
##外部调用,结束跟随
func stop_follow() -> void:
_current_state = State.IDLE
func get_base_position() -> Vector2:
return _final_position
func has_base_position() -> bool:
return _current_state == State.CHASING

View File

@ -11,6 +11,7 @@ var _current_offset := Vector2.ZERO
func _ready() -> void: func _ready() -> void:
if Engine.is_editor_hint(): if Engine.is_editor_hint():
return return
set_process(true) set_process(true)
func _exit_tree() -> void: func _exit_tree() -> void:

View File

@ -0,0 +1,9 @@
[gd_scene load_steps=2 format=3 uid="uid://csx2bji7s6xnl"]
[ext_resource type="Script" uid="uid://dckyyfvj25bxf" path="res://addons/reedcamera/scripts/ScreenRatioRect.gd" id="1_ljod6"]
[node name="DeadZoneDebug" type="CanvasLayer"]
layer = 1000
[node name="ScreenRatioRect" type="Node2D" parent="."]
script = ExtResource("1_ljod6")

View File

@ -0,0 +1,6 @@
class_name STT_Autoload extends SceneTriggerTarget
@export var autoload_name: StringName
func get_effect_target(owner: Node) -> Object:
return owner.get_tree().root.get_node_or_null("/root/%s" % autoload_name)

View File

@ -0,0 +1 @@
uid://cwxwsfl1mx7kc