diff --git a/_camera/PlateformerCamera.tscn b/_camera/PlateformerCamera.tscn index e5ecf16..0666550 100644 --- a/_camera/PlateformerCamera.tscn +++ b/_camera/PlateformerCamera.tscn @@ -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://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://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"] script = ExtResource("1_05blt") @@ -22,3 +23,8 @@ script = ExtResource("4_877nu") affect_position = true affect_zoom = true 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" diff --git a/_player/avatar.gd b/_player/avatar.gd index aa000c7..6408d0c 100644 --- a/_player/avatar.gd +++ b/_player/avatar.gd @@ -76,7 +76,6 @@ func _draw() -> void: func _process(delta: float) -> void: queue_redraw() - func set_move_input(dir: Vector2) -> void: m_input_intent_direction = dir diff --git a/_scene/level1/l0_s0.tscn b/_scene/level1/l0_s0.tscn index aad64c3..12c1031 100644 --- a/_scene/level1/l0_s0.tscn +++ b/_scene/level1/l0_s0.tscn @@ -119,7 +119,6 @@ script = ExtResource("10_g4f48") [node name="CameraAnchor" parent="Props" instance=ExtResource("11_o5yb1")] position = Vector2(-39, 1203) -zoom = Vector2(0.75, 0.75) [node name="[Prop_0000]" type="Node" parent="Props/CameraAnchor"] script = ExtResource("12_vhd7q") diff --git a/_scene/level1/l1_s2.tscn b/_scene/level1/l1_s2.tscn index 47b0a66..0d89e3d 100644 --- a/_scene/level1/l1_s2.tscn +++ b/_scene/level1/l1_s2.tscn @@ -134,8 +134,7 @@ init_act_id = 0 script = ExtResource("7_8ou3l") [node name="CameraAnchor" parent="Props" instance=ExtResource("8_dq7pn")] -position = Vector2(540, -400) -zoom = Vector2(0.75, 0.75) +position = Vector2(336, -385) limit_top = -335 limit_bottom = 240 limit_left = -427 @@ -159,10 +158,10 @@ state_id = 1 effects = Array[ExtResource("12_fmhh5")]([ExtResource("14_nnp13")]) [node name="PlayerTriggerVolumn" parent="Props" instance=ExtResource("15_lg3ok")] -visible = false position = Vector2(560, -480) [node name="CollisionShape2D" type="CollisionShape2D" parent="Props/PlayerTriggerVolumn"] +visible = false show_behind_parent = true position = Vector2(-25.5, -2) shape = SubResource("RectangleShape2D_oupin") diff --git a/_scene/scene_trigger_resource/default_switch.tres b/_scene/scene_trigger_resource/default_switch.tres index 1e18f5d..b1957b6 100644 --- a/_scene/scene_trigger_resource/default_switch.tres +++ b/_scene/scene_trigger_resource/default_switch.tres @@ -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://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://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://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"] [sub_resource type="Resource" id="Resource_yc616"] @@ -41,6 +42,22 @@ target = SubResource("Resource_kdh4c") effect = Array[ExtResource("4_g7ixm")]([SubResource("Resource_jd40h")]) 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"] script = ExtResource("8_kur88") node_path = NodePath("../Props/PlayerTriggerVolumn") @@ -50,5 +67,5 @@ metadata/_custom_type_script = "uid://cdprpen0jyr6d" [resource] script = ExtResource("2_cq8o1") 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" diff --git a/_shared/GlobalEvent.gd b/_shared/GlobalEvent.gd index dfa9a06..698bc24 100644 --- a/_shared/GlobalEvent.gd +++ b/_shared/GlobalEvent.gd @@ -6,6 +6,8 @@ signal player_dead(player: Player) var _cached_player_controller: PlayerController var _cached_player: Player +var _camera_follower : Node = null + ## player controller進入tree會注冊自己到Global func register_player_controller(pc: PlayerController) -> PlayerController: if not pc: return null @@ -18,6 +20,10 @@ func register_player(player: Player) -> Player: if not player: return null _cached_player = player + + ##如果我们缓存了一个camera_follower,在玩家重生的时候我们会让follower自动绑定 + if _camera_follower: + _camera_follower.register_follower(_cached_player) return _cached_player ## 外部快速获取Player @@ -28,6 +34,28 @@ func get_player() -> Player: func get_player_controller() -> PlayerController: 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死亡 func boradcast_player_dead_event(player:Player) -> void: player_dead.emit(player) diff --git a/addons/reedcamera/_data/CameraSystemConst.gd b/addons/reedcamera/_data/CameraSystemConst.gd index 88a49d5..46ab778 100644 --- a/addons/reedcamera/_data/CameraSystemConst.gd +++ b/addons/reedcamera/_data/CameraSystemConst.gd @@ -7,6 +7,10 @@ const CAMERA_SYSTEM_NAME : StringName = "ReedCameraSystem" const CAMERA_ANCHOR_NAME : StringName = "CameraAnchor" 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 #region GroupName diff --git a/addons/reedcamera/scripts/CameraPointer.gd b/addons/reedcamera/scripts/CameraPointer.gd index 461ce50..5774d10 100644 --- a/addons/reedcamera/scripts/CameraPointer.gd +++ b/addons/reedcamera/scripts/CameraPointer.gd @@ -4,6 +4,20 @@ class_name CameraPointer 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 _editor_valid := false var _runtime_registered := false @@ -17,6 +31,7 @@ var _pos_dirty := false var _offset_dirty := false var _zoom_dirty := false + func _enter_tree() -> void: if Engine.is_editor_hint(): call_deferred("_editor_verify") @@ -122,10 +137,9 @@ func _editor_verify() -> void: func _ready() -> void: if Engine.is_editor_hint(): return - - _camera = _find_camera() + if not _camera: - return + _camera = _find_camera() _request_register() @@ -169,6 +183,8 @@ func _emit_config_warning() -> void: ## ========================= ##获取相机 func get_camera() -> Camera2D: + if not _camera: + _camera = _find_camera() return _camera ##获取特定工具 @@ -178,6 +194,10 @@ func get_tool(tool_class: Script) -> Node: return c return null +##通过类型返回工具 +func get_tool_by_type(type:ToolType) -> Node: + return get_tool(type_script_map.get(type)) + ##获取所有工具 func get_tools() -> Array[CameraToolBasic]: var out: Array[CameraToolBasic] = [] diff --git a/addons/reedcamera/scripts/ScreenRatioRect.gd b/addons/reedcamera/scripts/ScreenRatioRect.gd new file mode 100644 index 0000000..b7fdd51 --- /dev/null +++ b/addons/reedcamera/scripts/ScreenRatioRect.gd @@ -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) diff --git a/addons/reedcamera/scripts/ScreenRatioRect.gd.uid b/addons/reedcamera/scripts/ScreenRatioRect.gd.uid new file mode 100644 index 0000000..6d51f88 --- /dev/null +++ b/addons/reedcamera/scripts/ScreenRatioRect.gd.uid @@ -0,0 +1 @@ +uid://dckyyfvj25bxf diff --git a/addons/reedcamera/scripts/camera_tools/CameraFollowController.gd b/addons/reedcamera/scripts/camera_tools/CameraFollowController.gd index 92eb39d..1e5e31f 100644 --- a/addons/reedcamera/scripts/camera_tools/CameraFollowController.gd +++ b/addons/reedcamera/scripts/camera_tools/CameraFollowController.gd @@ -2,67 +2,147 @@ extends CameraToolBasic class_name ReedCameraFollowController 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 var dead_zone_ratio := Rect2( - Vector2.ZERO, # 屏幕中心 - Vector2(0.4, 0.4) # 宽高(屏幕比例) -) +@export var dead_zone_ratio : Vector2 = Vector2(.6,.6) @export_group("Follow") @export var enabled_follow: bool = true +@export var follow_speed: float = 600.0 # 世界单位 / 秒 @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 _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 -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: 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 + + # 0. 读取相机的全局坐标 + _final_position = cam.global_position + + # 1. target 的屏幕坐标(Canvas Space) + var t_in_screen :Vector2 = \ + _follow_node2d.get_global_transform_with_canvas().get_origin() + + var screen_size : Vector2 = _get_camera_system().get_screen_size() + var screen_center : Vector2 = screen_size * 0.5 + var dead_half : Vector2 = screen_size * dead_zone_ratio * 0.5 + + # 2. 获得移动方向 + var offset := \ + _compute_deadzone_offset( + t_in_screen, + screen_center, + dead_half ) + + if offset == Vector2.ZERO: + _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 - # 蔚蓝感:滞后 lerp - _pos = _pos.lerp(_desired_pos, follow_lerp) + 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: if _camera: return _camera @@ -74,11 +154,38 @@ func _get_camera_from_pointer() -> Camera2D: 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) +## 获取全局相机管理器 +func _get_camera_system() -> Object: + if _sys: + return _sys + + if Engine.has_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME): + _sys = Engine.get_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME) + + return _sys - var size := screen_size / zoom - return Rect2(cam.global_position - size * 0.5, size) + +##外部调用,设置一个相机系统的跟随者 +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 diff --git a/addons/reedcamera/scripts/camera_tools/CameraShakeController.gd b/addons/reedcamera/scripts/camera_tools/CameraShakeController.gd index 1ee07eb..2b48900 100644 --- a/addons/reedcamera/scripts/camera_tools/CameraShakeController.gd +++ b/addons/reedcamera/scripts/camera_tools/CameraShakeController.gd @@ -11,6 +11,7 @@ var _current_offset := Vector2.ZERO func _ready() -> void: if Engine.is_editor_hint(): return + set_process(true) func _exit_tree() -> void: diff --git a/addons/reedcamera/scripts/camera_tools/DeadZoneDebug.tscn b/addons/reedcamera/scripts/camera_tools/DeadZoneDebug.tscn new file mode 100644 index 0000000..5f9004a --- /dev/null +++ b/addons/reedcamera/scripts/camera_tools/DeadZoneDebug.tscn @@ -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") diff --git a/addons/reedscene/scene/scene_trigger/STT_Autoload.gd b/addons/reedscene/scene/scene_trigger/STT_Autoload.gd new file mode 100644 index 0000000..f4fae1f --- /dev/null +++ b/addons/reedscene/scene/scene_trigger/STT_Autoload.gd @@ -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) diff --git a/addons/reedscene/scene/scene_trigger/STT_Autoload.gd.uid b/addons/reedscene/scene/scene_trigger/STT_Autoload.gd.uid new file mode 100644 index 0000000..1a3c930 --- /dev/null +++ b/addons/reedscene/scene/scene_trigger/STT_Autoload.gd.uid @@ -0,0 +1 @@ +uid://cwxwsfl1mx7kc