Compare commits
No commits in common. "b18a1c0294335c009291f7298b8b5f847fcbd9ad" and "4f109c218bbb0f402f77b31ed425a868d38d307e" have entirely different histories.
b18a1c0294
...
4f109c218b
|
Before Width: | Height: | Size: 869 B After Width: | Height: | Size: 869 B |
|
|
@ -3,15 +3,15 @@
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://bsdmq0essfmpk"
|
uid="uid://bsdmq0essfmpk"
|
||||||
path="res://.godot/imported/camera_anchor_icon.svg-d54e4ec18108e371c1abc23152af31de.ctex"
|
path="res://.godot/imported/camera_anchor_icon.svg-bc0c9f7b183031f0db701d2e858a9063.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://addons/reedcamera/icon/camera_anchor_icon.svg"
|
source_file="res://_asset/icon/camera_anchor_icon.svg"
|
||||||
dest_files=["res://.godot/imported/camera_anchor_icon.svg-d54e4ec18108e371c1abc23152af31de.ctex"]
|
dest_files=["res://.godot/imported/camera_anchor_icon.svg-bc0c9f7b183031f0db701d2e858a9063.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
|
|
@ -1,265 +0,0 @@
|
||||||
#'''全局的相机管理器
|
|
||||||
#
|
|
||||||
#======= 外部调用函数 =======
|
|
||||||
#
|
|
||||||
#'''
|
|
||||||
#@tool
|
|
||||||
extends Node
|
|
||||||
#
|
|
||||||
#@onready var camera_2d: Camera2D = %Camera2D
|
|
||||||
#@onready var camera_shake_player: CameraShakePlayer = %CameraShakePlayer
|
|
||||||
#
|
|
||||||
#var _cached_anchors: Array[CameraAnchor] = []
|
|
||||||
#var _current_anchor: CameraAnchor
|
|
||||||
#var _switch_tween: Tween
|
|
||||||
#var _player_remote: RemoteTransform2D
|
|
||||||
#var _base_camera_pos := Vector2.ZERO
|
|
||||||
#
|
|
||||||
###标记位,用来检测当前帧是否存在相机切换
|
|
||||||
#var _switch_scheduled := false
|
|
||||||
#var _dirty := false
|
|
||||||
#var _screen_size : Vector2i
|
|
||||||
#
|
|
||||||
### 玩家关卡内静态相机
|
|
||||||
#const CAMERA_FOLLOWER:= preload("res://camera/camera_follower.tscn")
|
|
||||||
#
|
|
||||||
#func _ready() -> void:
|
|
||||||
## Setting default screensize
|
|
||||||
#_screen_size = Vector2i(
|
|
||||||
#ProjectSettings.get_setting("display/window/size/viewport_width"),
|
|
||||||
#ProjectSettings.get_setting("display/window/size/viewport_height")
|
|
||||||
#)
|
|
||||||
#
|
|
||||||
## For editor
|
|
||||||
#if Engine.is_editor_hint():
|
|
||||||
#ProjectSettings.settings_changed.connect(func():
|
|
||||||
#_screen_size = Vector2i(
|
|
||||||
#ProjectSettings.get_setting("display/window/size/viewport_width"),
|
|
||||||
#ProjectSettings.get_setting("display/window/size/viewport_height")
|
|
||||||
#)
|
|
||||||
#)
|
|
||||||
## For runtime
|
|
||||||
#else:
|
|
||||||
#get_tree().get_root().size_changed.connect(func():
|
|
||||||
#_screen_size = get_viewport().get_visible_rect().size
|
|
||||||
#)
|
|
||||||
#
|
|
||||||
#func _editor_ready() -> void:
|
|
||||||
#ProjectSettings.settings_changed.connect(func():
|
|
||||||
#_screen_size = Vector2i(
|
|
||||||
#ProjectSettings.get_setting("display/window/size/viewport_width"),
|
|
||||||
#ProjectSettings.get_setting("display/window/size/viewport_height")
|
|
||||||
#)
|
|
||||||
#)
|
|
||||||
#
|
|
||||||
#func _runtime_ready() -> void:
|
|
||||||
#get_tree().get_root().size_changed.connect(func():
|
|
||||||
#_screen_size = get_viewport().get_visible_rect().size
|
|
||||||
#)
|
|
||||||
#
|
|
||||||
##func _process(delta):
|
|
||||||
##if not Engine.is_editor_hint():
|
|
||||||
##_runtime_process(delta)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#func _runtime_process(delta):
|
|
||||||
#if not camera_2d:
|
|
||||||
#return
|
|
||||||
#
|
|
||||||
#var shake_offset := camera_shake_player.update(delta)
|
|
||||||
#camera_2d.global_position = _base_camera_pos + shake_offset
|
|
||||||
#
|
|
||||||
#func _on_player_spawned(new_player: Player) -> void:
|
|
||||||
#if _current_anchor and _current_anchor.follow_player:
|
|
||||||
#_bind_camera_follow_to_player(new_player)
|
|
||||||
#
|
|
||||||
#func _on_player_dead() -> void:
|
|
||||||
#return
|
|
||||||
#
|
|
||||||
### 绑定camera 到 player
|
|
||||||
#func _bind_camera_follow_to_player(player: Player) -> void:
|
|
||||||
#if _player_remote and is_instance_valid(_player_remote):
|
|
||||||
#_player_remote.queue_free()
|
|
||||||
#_player_remote = null
|
|
||||||
#
|
|
||||||
#if not is_instance_valid(player):
|
|
||||||
#return
|
|
||||||
#
|
|
||||||
#var rt := RemoteTransform2D.new()
|
|
||||||
#rt.name = "__CameraAnchorFollow"
|
|
||||||
#rt.remote_path = camera_2d.get_path()
|
|
||||||
#rt.update_position = true
|
|
||||||
#rt.update_rotation = false
|
|
||||||
#rt.update_scale = false
|
|
||||||
#
|
|
||||||
#player.add_child(rt)
|
|
||||||
#_player_remote = rt
|
|
||||||
#
|
|
||||||
### 外部获取玩家全局相机
|
|
||||||
#func get_cached_camera() -> Camera2D:
|
|
||||||
#return camera_2d
|
|
||||||
#
|
|
||||||
### 注册一个相机锚点
|
|
||||||
#func register_anchor(anchor: CameraAnchor) -> void:
|
|
||||||
#if anchor in _cached_anchors:
|
|
||||||
#return
|
|
||||||
#_cached_anchors.append(anchor)
|
|
||||||
#anchor.on_priority_change.connect(on_anchor_priority_changed)
|
|
||||||
#_request_evaluate()
|
|
||||||
#
|
|
||||||
### 当相机锚点的权重改变时,向管理器触发事件
|
|
||||||
#func on_anchor_priority_changed(priority:int, anchor: CameraAnchor) -> void:
|
|
||||||
#_request_evaluate()
|
|
||||||
#
|
|
||||||
### 注销一个相机锚点
|
|
||||||
#func unregister_anchor(anchor: CameraAnchor) -> void:
|
|
||||||
#_cached_anchors.erase(anchor)
|
|
||||||
#if _current_anchor == anchor:
|
|
||||||
#_current_anchor = null
|
|
||||||
#_request_evaluate()
|
|
||||||
#
|
|
||||||
#func _request_evaluate() -> void:
|
|
||||||
#_dirty = true
|
|
||||||
#if _switch_scheduled:
|
|
||||||
#return
|
|
||||||
#_switch_scheduled = true
|
|
||||||
#call_deferred("_commit_camera_anchor")
|
|
||||||
#
|
|
||||||
#func _commit_camera_anchor() -> void:
|
|
||||||
#_switch_scheduled = false
|
|
||||||
#if not _dirty:
|
|
||||||
#return
|
|
||||||
#_dirty = false
|
|
||||||
#
|
|
||||||
## 清理无效
|
|
||||||
#_cached_anchors = _cached_anchors.filter(func(a): return is_instance_valid(a))
|
|
||||||
#
|
|
||||||
#var winner: CameraAnchor = _pick_best_anchor()
|
|
||||||
#
|
|
||||||
#if winner == null:
|
|
||||||
#return
|
|
||||||
#
|
|
||||||
#if winner == _current_anchor:
|
|
||||||
#return
|
|
||||||
#
|
|
||||||
#switch_anchor(winner)
|
|
||||||
#
|
|
||||||
#func _pick_best_anchor() -> CameraAnchor:
|
|
||||||
#var best: CameraAnchor = null
|
|
||||||
#var best_p := -INF
|
|
||||||
#
|
|
||||||
#for a in _cached_anchors:
|
|
||||||
#if not a.enabled:
|
|
||||||
#continue
|
|
||||||
#if a._priority > best_p:
|
|
||||||
#best_p = a._priority
|
|
||||||
#best = a
|
|
||||||
#
|
|
||||||
#return best
|
|
||||||
#
|
|
||||||
### 排序已有的锚点
|
|
||||||
#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)
|
|
||||||
#_current_anchor = a
|
|
||||||
#return
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
###应用Anchor的Limit
|
|
||||||
#func _apply_anchor_limits(anchor: CameraAnchor) -> void:
|
|
||||||
#if not camera_2d:
|
|
||||||
#return
|
|
||||||
#camera_2d.limit_left = anchor.global_position.x + anchor.limit_left
|
|
||||||
#camera_2d.limit_right = anchor.global_position.x + anchor.limit_right
|
|
||||||
#camera_2d.limit_top = anchor.global_position.y + anchor.limit_top
|
|
||||||
#camera_2d.limit_bottom = anchor.global_position.y + anchor.limit_bottom
|
|
||||||
#
|
|
||||||
#func _clear_camera_limits() -> void:
|
|
||||||
#if not camera_2d:
|
|
||||||
#return
|
|
||||||
#camera_2d.limit_left = -10000000
|
|
||||||
#camera_2d.limit_right = 10000000
|
|
||||||
#camera_2d.limit_top = -10000000
|
|
||||||
#camera_2d.limit_bottom = 10000000
|
|
||||||
#
|
|
||||||
### 切换相机
|
|
||||||
#func switch_anchor(target_anchor: CameraAnchor) -> void:
|
|
||||||
#if target_anchor == null:
|
|
||||||
#return
|
|
||||||
#if target_anchor == _current_anchor:
|
|
||||||
#return
|
|
||||||
#if not is_instance_valid(camera_2d):
|
|
||||||
#return
|
|
||||||
#
|
|
||||||
##优先清除已有的remote
|
|
||||||
#if _player_remote:
|
|
||||||
#_player_remote.queue_free()
|
|
||||||
#_player_remote = null
|
|
||||||
#
|
|
||||||
## 中断旧 Tween
|
|
||||||
#if _switch_tween and _switch_tween.is_running():
|
|
||||||
#_switch_tween.kill()
|
|
||||||
#_switch_tween = null
|
|
||||||
#
|
|
||||||
#var camera := camera_2d
|
|
||||||
#var blend_time : float = max(target_anchor.blend_time, 0.001)
|
|
||||||
#
|
|
||||||
#_clear_camera_limits()
|
|
||||||
#
|
|
||||||
#_switch_tween = get_tree().create_tween()
|
|
||||||
#_switch_tween.set_ignore_time_scale(true)
|
|
||||||
#_switch_tween.set_trans(Tween.TRANS_CUBIC)
|
|
||||||
#_switch_tween.set_ease(Tween.EASE_OUT)
|
|
||||||
#
|
|
||||||
## ===== 位置 =====
|
|
||||||
#_switch_tween.tween_property(
|
|
||||||
#self,
|
|
||||||
#"_base_camera_pos",
|
|
||||||
#target_anchor.global_position,
|
|
||||||
#blend_time
|
|
||||||
#)
|
|
||||||
#
|
|
||||||
## ===== Zoom =====
|
|
||||||
#_switch_tween.parallel().tween_property(
|
|
||||||
#camera,
|
|
||||||
#"zoom",
|
|
||||||
#target_anchor.zoom,
|
|
||||||
#blend_time * 1.5
|
|
||||||
#)
|
|
||||||
#
|
|
||||||
## 完成回调
|
|
||||||
#_switch_tween.finished.connect(func():
|
|
||||||
#_current_anchor = target_anchor
|
|
||||||
#_update_anchor_follow_state(target_anchor)
|
|
||||||
#_apply_anchor_limits(target_anchor)
|
|
||||||
#)
|
|
||||||
#
|
|
||||||
#_current_anchor = target_anchor
|
|
||||||
#
|
|
||||||
#func _update_anchor_follow_state(anchor: CameraAnchor) -> void:
|
|
||||||
#if not anchor.follow_player:
|
|
||||||
#return
|
|
||||||
#
|
|
||||||
#var player := GlobalEvent.get_player()
|
|
||||||
#if player:
|
|
||||||
#_bind_camera_follow_to_player(player)
|
|
||||||
#
|
|
||||||
## ==========================
|
|
||||||
## External API
|
|
||||||
## ==========================
|
|
||||||
### 重置所有的Camera的_priority
|
|
||||||
#func reset_all_camera_priority() -> void:
|
|
||||||
#for a in _cached_anchors:
|
|
||||||
#a._priority = 0
|
|
||||||
#
|
|
||||||
### 返回屏幕比例
|
|
||||||
#func get_screen_size() -> Vector2i:
|
|
||||||
#return _screen_size
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
[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")
|
|
||||||
|
|
||||||
[node name="CameraPointer" type="Node" parent="."]
|
|
||||||
script = ExtResource("1_e7rkk")
|
|
||||||
metadata/_custom_type_script = "uid://py4h5jxlncro"
|
|
||||||
|
|
||||||
[node name="ReedCameraShakeController" type="Node" parent="CameraPointer"]
|
|
||||||
script = ExtResource("2_rbequ")
|
|
||||||
affect_offset = true
|
|
||||||
metadata/_custom_type_script = "uid://dwr1s51svvank"
|
|
||||||
|
|
||||||
[node name="ReedCameraAnchorController" type="Node" parent="CameraPointer"]
|
|
||||||
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"
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
extends RemoteTransform2D
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
pass
|
|
||||||
#var global_camera: Camera2D = CameraSystem.get_cached_camera()
|
|
||||||
#if not global_camera:
|
|
||||||
#push_error("[CameraFollower]:No Global Camera Founded")
|
|
||||||
#return
|
|
||||||
#remote_path = global_camera.get_path()
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
extends Camera2D
|
|
||||||
|
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
|
||||||
if event.is_action_pressed("ui_accept"):
|
|
||||||
$CameraPointer/ReedCameraShakeController.play_shake(preload("res://addons/reedcamera/_example/test_shake.tres"))
|
|
||||||
#elif event.is_action_pressed("ui_right"):
|
|
||||||
#self.global_position += Vector2(100,0)
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://djk7tg2puphgv
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
[gd_scene load_steps=15 format=3 uid="uid://3vc8ojbiyy5w"]
|
[gd_scene load_steps=14 format=3 uid="uid://3vc8ojbiyy5w"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://crgac4manhoud" path="res://_game/game.gd" id="1_yksyv"]
|
[ext_resource type="Script" uid="uid://crgac4manhoud" path="res://_game/game.gd" id="1_yksyv"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cvqehvdjpoar4" path="res://_player/player_controller.tscn" id="2_x2i0j"]
|
[ext_resource type="PackedScene" uid="uid://cvqehvdjpoar4" path="res://_player/player_controller.tscn" id="2_x2i0j"]
|
||||||
[ext_resource type="PackedScene" uid="uid://sursemsbf1lg" path="res://_scene/level1/l0_s0.tscn" id="3_4ifj7"]
|
[ext_resource type="PackedScene" uid="uid://sursemsbf1lg" path="res://_scene/level1/l0_s0.tscn" id="3_4ifj7"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cw6buluknvjj" path="res://_camera/PlateformerCamera.tscn" id="3_enubi"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cd88ydqhdo28" path="res://_scene/level1/l1_s1.tscn" id="4_m1t3p"]
|
[ext_resource type="PackedScene" uid="uid://cd88ydqhdo28" path="res://_scene/level1/l1_s1.tscn" id="4_m1t3p"]
|
||||||
[ext_resource type="PackedScene" uid="uid://djs1eg5y008cs" path="res://_scene/level1/l1_s2.tscn" id="5_5s0xe"]
|
[ext_resource type="PackedScene" uid="uid://djs1eg5y008cs" path="res://_scene/level1/l1_s2.tscn" id="5_5s0xe"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dh43kt0l28qd5" path="res://_scene/level1/l1_s3.tscn" id="6_ktxjv"]
|
[ext_resource type="PackedScene" uid="uid://dh43kt0l28qd5" path="res://_scene/level1/l1_s3.tscn" id="6_ktxjv"]
|
||||||
|
|
@ -20,8 +19,6 @@ script = ExtResource("1_yksyv")
|
||||||
|
|
||||||
[node name="PlayerController" parent="." instance=ExtResource("2_x2i0j")]
|
[node name="PlayerController" parent="." instance=ExtResource("2_x2i0j")]
|
||||||
|
|
||||||
[node name="PlateformerCamera" parent="." instance=ExtResource("3_enubi")]
|
|
||||||
|
|
||||||
[node name="L0_S0" parent="." instance=ExtResource("3_4ifj7")]
|
[node name="L0_S0" parent="." instance=ExtResource("3_4ifj7")]
|
||||||
|
|
||||||
[node name="L1_S1" parent="." instance=ExtResource("4_m1t3p")]
|
[node name="L1_S1" parent="." instance=ExtResource("4_m1t3p")]
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@ extends Node2D
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
#$L0_S0.switch_act_by_id(1)
|
#$L0_S0.switch_act_by_id(1)
|
||||||
$L1_S1.switch_act_by_id(1)
|
#$L1_S1.switch_act_by_id(1)
|
||||||
#$L1_S2.switch_act_by_id(1)
|
#$L1_S2.switch_act_by_id(1)
|
||||||
#$L1_S3.switch_act_by_id(1)
|
#$L1_S3.switch_act_by_id(1)
|
||||||
#$L1_S4.switch_act_by_id(1)
|
#$L1_S4.switch_act_by_id(1)
|
||||||
#$L1_S5.switch_act_by_id(1)
|
#$L1_S5.switch_act_by_id(1)
|
||||||
#$L1_S6.switch_act_by_id(1)
|
#$L1_S6.switch_act_by_id(1)
|
||||||
#$L1_S7.switch_act_by_id(1)
|
$L1_S7.switch_act_by_id(1)
|
||||||
#$L1_S8.switch_act_by_id(1)
|
#$L1_S8.switch_act_by_id(1)
|
||||||
#$L1_S9.switch_act_by_id(1)
|
#$L1_S9.switch_act_by_id(1)
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
[ext_resource type="Script" uid="uid://isu8onknb75o" path="res://_player/states/character_state_machine.gd" id="1_wvs5h"]
|
[ext_resource type="Script" uid="uid://isu8onknb75o" path="res://_player/states/character_state_machine.gd" id="1_wvs5h"]
|
||||||
[ext_resource type="Script" uid="uid://15n8yfyr4eqj" path="res://_player/states/grounded.gd" id="2_5p50s"]
|
[ext_resource type="Script" uid="uid://15n8yfyr4eqj" path="res://_player/states/grounded.gd" id="2_5p50s"]
|
||||||
[ext_resource type="Script" uid="uid://dcfq4wnx2g6bs" path="res://_player/player_locomotion.gd" id="2_11vl8"]
|
[ext_resource type="Script" uid="uid://dcfq4wnx2g6bs" path="res://_player/player_locomotion.gd" id="2_11vl8"]
|
||||||
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_camera/camera_shake/CameraShakePreset.gd" id="2_u7cua"]
|
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_shared/camera/camera_shake/CameraShakePreset.gd" id="2_u7cua"]
|
||||||
[ext_resource type="Resource" uid="uid://iv3hfxqm5503" path="res://_camera/camera_shake/CSP_HorizontalOnly.tres" id="3_1a1t3"]
|
[ext_resource type="Resource" uid="uid://iv3hfxqm5503" path="res://_shared/camera/camera_shake/CSP_HorizontalOnly.tres" id="3_1a1t3"]
|
||||||
[ext_resource type="Resource" uid="uid://bs3cqsp23047i" path="res://_camera/camera_shake/CSP_VerticalOnly.tres" id="4_01uoa"]
|
[ext_resource type="Resource" uid="uid://bs3cqsp23047i" path="res://_shared/camera/camera_shake/CSP_VerticalOnly.tres" id="4_01uoa"]
|
||||||
[ext_resource type="Script" uid="uid://b5hkfpjbye70" path="res://_player/states/idle.gd" id="4_30i7g"]
|
[ext_resource type="Script" uid="uid://b5hkfpjbye70" path="res://_player/states/idle.gd" id="4_30i7g"]
|
||||||
[ext_resource type="BlackboardPlan" uid="uid://nlw7rxugv5uh" path="res://_player/bbp_player.tres" id="4_mwufa"]
|
[ext_resource type="BlackboardPlan" uid="uid://nlw7rxugv5uh" path="res://_player/bbp_player.tres" id="4_mwufa"]
|
||||||
[ext_resource type="Resource" uid="uid://cs50mkt830f8r" path="res://_shared/camera/camera_shake/CSP_XY.tres" id="5_ciuu3"]
|
[ext_resource type="Resource" uid="uid://cs50mkt830f8r" path="res://_shared/camera/camera_shake/CSP_XY.tres" id="5_ciuu3"]
|
||||||
|
|
@ -75,7 +75,6 @@ position = Vector2(0, 5.75)
|
||||||
shape = SubResource("RectangleShape2D_qnulu")
|
shape = SubResource("RectangleShape2D_qnulu")
|
||||||
|
|
||||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||||
visible = false
|
|
||||||
texture_filter = 1
|
texture_filter = 1
|
||||||
position = Vector2(0, 3.9999998)
|
position = Vector2(0, 3.9999998)
|
||||||
scale = Vector2(0.1, 0.1)
|
scale = Vector2(0.1, 0.1)
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ 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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
[gd_scene load_steps=5 format=3 uid="uid://ck8m7revy150r"]
|
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://gwhff4qaouxy" path="res://_player/Avatar.tscn" id="1_irquc"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://dted7geb331y2" path="res://_asset/ksw/character.png" id="2_350jv"]
|
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_350jv"]
|
|
||||||
radius = 41.0
|
|
||||||
height = 134.0
|
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_e1o4i"]
|
|
||||||
radius = 45.0
|
|
||||||
height = 145.0
|
|
||||||
|
|
||||||
[node name="Avatar" instance=ExtResource("1_irquc")]
|
|
||||||
|
|
||||||
[node name="CollisionShape2D" parent="." index="1"]
|
|
||||||
visible = false
|
|
||||||
shape = SubResource("CapsuleShape2D_350jv")
|
|
||||||
|
|
||||||
[node name="Sprite2D" parent="." index="2"]
|
|
||||||
visible = true
|
|
||||||
texture_filter = 0
|
|
||||||
texture = ExtResource("2_350jv")
|
|
||||||
|
|
||||||
[node name="LocomotionComponent" parent="." index="5"]
|
|
||||||
_can_move = false
|
|
||||||
|
|
||||||
[node name="CollisionShape2D" parent="HitBox" index="0"]
|
|
||||||
visible = false
|
|
||||||
position = Vector2(0, 0)
|
|
||||||
shape = SubResource("CapsuleShape2D_e1o4i")
|
|
||||||
|
|
||||||
[editable path="LocomotionComponent/WallDetector"]
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
[gd_scene load_steps=5 format=3 uid="uid://ck8m7revy150r"]
|
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://gwhff4qaouxy" path="res://_player/Avatar.tscn" id="1_irquc"]
|
|
||||||
[ext_resource type="Texture2D" uid="uid://dted7geb331y2" path="res://_asset/ksw/character.png" id="2_350jv"]
|
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_350jv"]
|
|
||||||
radius = 41.0
|
|
||||||
height = 134.0
|
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_e1o4i"]
|
|
||||||
radius = 45.0
|
|
||||||
height = 145.0
|
|
||||||
|
|
||||||
[node name="Avatar" instance=ExtResource("1_irquc")]
|
|
||||||
|
|
||||||
[node name="CollisionShape2D" parent="." index="1"]
|
|
||||||
visible = false
|
|
||||||
shape = SubResource("CapsuleShape2D_350jv")
|
|
||||||
|
|
||||||
[node name="Sprite2D" parent="." index="2"]
|
|
||||||
visible = true
|
|
||||||
texture_filter = 0
|
|
||||||
texture = ExtResource("2_350jv")
|
|
||||||
|
|
||||||
[node name="CollisionShape2D" parent="HitBox" index="0"]
|
|
||||||
visible = false
|
|
||||||
position = Vector2(0, 0)
|
|
||||||
shape = SubResource("CapsuleShape2D_e1o4i")
|
|
||||||
|
|
||||||
[editable path="LocomotionComponent/WallDetector"]
|
|
||||||
|
|
@ -44,8 +44,8 @@ func _enter() -> void:
|
||||||
elif i == 3 or i == 7:
|
elif i == 3 or i == 7:
|
||||||
csp = agent.camera_shake_preset.get("xy_light")
|
csp = agent.camera_shake_preset.get("xy_light")
|
||||||
|
|
||||||
#if csp:
|
if csp:
|
||||||
#CameraSystem.camera_shake_player.play(csp)
|
CameraSystem.camera_shake_player.play(csp)
|
||||||
|
|
||||||
if root.grap_hook_state._jump_grace_timer > 0:
|
if root.grap_hook_state._jump_grace_timer > 0:
|
||||||
_hook_to_jump()
|
_hook_to_jump()
|
||||||
|
|
|
||||||
|
|
@ -101,5 +101,4 @@ func respawn_avatar() -> CharacterBody2D:
|
||||||
new_avatar.position = self.global_position
|
new_avatar.position = self.global_position
|
||||||
get_tree().current_scene.add_child(new_avatar)
|
get_tree().current_scene.add_child(new_avatar)
|
||||||
|
|
||||||
GlobalEvent.player_spawned.emit(new_avatar)
|
|
||||||
return new_avatar
|
return new_avatar
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="8_0m4o0"]
|
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="8_0m4o0"]
|
||||||
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="9_1oohu"]
|
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="9_1oohu"]
|
||||||
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="10_g4f48"]
|
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="10_g4f48"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="11_o5yb1"]
|
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="11_o5yb1"]
|
||||||
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="12_vhd7q"]
|
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="12_vhd7q"]
|
||||||
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="13_5fsuc"]
|
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="13_5fsuc"]
|
||||||
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="14_rxcsc"]
|
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="14_rxcsc"]
|
||||||
|
|
@ -119,6 +119,7 @@ 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")
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="5_ubvm0"]
|
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="5_ubvm0"]
|
||||||
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_r0e2c"]
|
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_r0e2c"]
|
||||||
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="7_hd3du"]
|
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="7_hd3du"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="8_vjpkl"]
|
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="8_vjpkl"]
|
||||||
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="9_ctwrc"]
|
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="9_ctwrc"]
|
||||||
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="10_0u6xi"]
|
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="10_0u6xi"]
|
||||||
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="11_hatj6"]
|
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="11_hatj6"]
|
||||||
|
|
@ -119,6 +119,7 @@ script = ExtResource("7_hd3du")
|
||||||
|
|
||||||
[node name="CameraAnchor" parent="Props" instance=ExtResource("8_vjpkl")]
|
[node name="CameraAnchor" parent="Props" instance=ExtResource("8_vjpkl")]
|
||||||
position = Vector2(-41, 0)
|
position = Vector2(-41, 0)
|
||||||
|
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("9_ctwrc")
|
script = ExtResource("9_ctwrc")
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[ext_resource type="Resource" uid="uid://bym4pb0ellj7b" path="res://_scene/scene_trigger_resource/default_switch.tres" id="5_fdfto"]
|
[ext_resource type="Resource" uid="uid://bym4pb0ellj7b" path="res://_scene/scene_trigger_resource/default_switch.tres" id="5_fdfto"]
|
||||||
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_agny0"]
|
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_agny0"]
|
||||||
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="7_8ou3l"]
|
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="7_8ou3l"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="8_dq7pn"]
|
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="8_dq7pn"]
|
||||||
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="9_fdfto"]
|
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="9_fdfto"]
|
||||||
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="10_uerbs"]
|
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="10_uerbs"]
|
||||||
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="11_w12cs"]
|
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="11_w12cs"]
|
||||||
|
|
@ -134,11 +134,13 @@ 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(336, -385)
|
position = Vector2(540, -400)
|
||||||
|
zoom = Vector2(0.75, 0.75)
|
||||||
limit_top = -335
|
limit_top = -335
|
||||||
limit_bottom = 240
|
limit_bottom = 240
|
||||||
limit_left = -427
|
limit_left = -427
|
||||||
limit_right = 427
|
limit_right = 427
|
||||||
|
follow_player = true
|
||||||
|
|
||||||
[node name="[Prop_0000]" type="Node" parent="Props/CameraAnchor"]
|
[node name="[Prop_0000]" type="Node" parent="Props/CameraAnchor"]
|
||||||
script = ExtResource("9_fdfto")
|
script = ExtResource("9_fdfto")
|
||||||
|
|
@ -161,7 +163,6 @@ effects = Array[ExtResource("12_fmhh5")]([ExtResource("14_nnp13")])
|
||||||
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")
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="5_vajwc"]
|
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="5_vajwc"]
|
||||||
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_td1yf"]
|
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_td1yf"]
|
||||||
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="7_pawhc"]
|
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="7_pawhc"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="8_x0ktb"]
|
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="8_x0ktb"]
|
||||||
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="9_03jph"]
|
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="9_03jph"]
|
||||||
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="10_6tjqf"]
|
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="10_6tjqf"]
|
||||||
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="11_vl8fy"]
|
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="11_vl8fy"]
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="5_qtvqv"]
|
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="5_qtvqv"]
|
||||||
[ext_resource type="Resource" uid="uid://bym4pb0ellj7b" path="res://_scene/scene_trigger_resource/default_switch.tres" id="5_x87uk"]
|
[ext_resource type="Resource" uid="uid://bym4pb0ellj7b" path="res://_scene/scene_trigger_resource/default_switch.tres" id="5_x87uk"]
|
||||||
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_qtvqv"]
|
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="6_qtvqv"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="8_6bhoi"]
|
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="8_6bhoi"]
|
||||||
[ext_resource type="TileSet" uid="uid://doepkfp83k0lb" path="res://_tileset/test.tres" id="8_wofhb"]
|
[ext_resource type="TileSet" uid="uid://doepkfp83k0lb" path="res://_tileset/test.tres" id="8_wofhb"]
|
||||||
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="9_0dl6r"]
|
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="9_0dl6r"]
|
||||||
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="10_sv1n5"]
|
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="10_sv1n5"]
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_c6mvs"]
|
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_c6mvs"]
|
||||||
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_ug4by"]
|
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_ug4by"]
|
||||||
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_c10nq"]
|
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_c10nq"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="10_xrx0u"]
|
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="10_xrx0u"]
|
||||||
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_q6hv2"]
|
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_q6hv2"]
|
||||||
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_3vve2"]
|
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_3vve2"]
|
||||||
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_fqjrf"]
|
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_fqjrf"]
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_u3uxu"]
|
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_u3uxu"]
|
||||||
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_n5ng2"]
|
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_n5ng2"]
|
||||||
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_v8ejv"]
|
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_v8ejv"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="10_fwa5x"]
|
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="10_fwa5x"]
|
||||||
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_mlg0v"]
|
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_mlg0v"]
|
||||||
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_3yfjx"]
|
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_3yfjx"]
|
||||||
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_k40sn"]
|
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_k40sn"]
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_u3uxu"]
|
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_u3uxu"]
|
||||||
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_n5ng2"]
|
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_n5ng2"]
|
||||||
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_v8ejv"]
|
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_v8ejv"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="10_fwa5x"]
|
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="10_fwa5x"]
|
||||||
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_mlg0v"]
|
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_mlg0v"]
|
||||||
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_3yfjx"]
|
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_3yfjx"]
|
||||||
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_k40sn"]
|
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_k40sn"]
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_o10qt"]
|
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_o10qt"]
|
||||||
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_nkrpp"]
|
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_nkrpp"]
|
||||||
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_ru3iu"]
|
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_ru3iu"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="10_8v4hu"]
|
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="10_8v4hu"]
|
||||||
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_nkttg"]
|
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_nkttg"]
|
||||||
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_7fah6"]
|
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_7fah6"]
|
||||||
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_ot6uu"]
|
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_ot6uu"]
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_2ws8l"]
|
[ext_resource type="Script" uid="uid://fxpk2ot6otfh" path="res://addons/reedscene/act/Act.gd" id="7_2ws8l"]
|
||||||
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_kk8q0"]
|
[ext_resource type="Script" uid="uid://baqgorvlumyju" path="res://addons/reedscene/act/SingleAct.gd" id="8_kk8q0"]
|
||||||
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_uiu2l"]
|
[ext_resource type="Script" uid="uid://pxjf5vst08eo" path="res://addons/reedscene/prop/PropManager.gd" id="9_uiu2l"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_camera/CameraAnchor.tscn" id="10_npsqr"]
|
[ext_resource type="PackedScene" uid="uid://bflwr7cryd2l0" path="res://_shared/camera/CameraAnchor.tscn" id="10_npsqr"]
|
||||||
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_gkqbq"]
|
[ext_resource type="Script" uid="uid://b4menkyub4ce7" path="res://addons/reedscene/prop/PropComponent.gd" id="11_gkqbq"]
|
||||||
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_64ehn"]
|
[ext_resource type="Script" uid="uid://di41kt2tj34c2" path="res://addons/reedscene/prop/StateManager.gd" id="12_64ehn"]
|
||||||
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_a1xcn"]
|
[ext_resource type="Script" uid="uid://7lml6d1t5xtq" path="res://addons/reedscene/prop/PropState.gd" id="13_a1xcn"]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_resource type="Resource" script_class="SceneTrigger" load_steps=20 format=3 uid="uid://bym4pb0ellj7b"]
|
[gd_resource type="Resource" script_class="SceneTrigger" load_steps=16 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,7 +7,6 @@
|
||||||
[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"]
|
||||||
|
|
@ -42,22 +41,6 @@ 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")
|
||||||
|
|
@ -67,5 +50,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"), SubResource("Resource_g7ixm")])
|
trigger_effect_pairs = Array[ExtResource("3_m0qh3")]([SubResource("Resource_vv5v7"), SubResource("Resource_ig5jt")])
|
||||||
metadata/_custom_type_script = "uid://ons77en82uls"
|
metadata/_custom_type_script = "uid://ons77en82uls"
|
||||||
|
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
extends Node
|
|
||||||
|
|
||||||
signal player_spawned(player: Player)
|
|
||||||
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
|
|
||||||
|
|
||||||
_cached_player_controller = pc
|
|
||||||
return _cached_player_controller
|
|
||||||
|
|
||||||
## player進入tree會注冊自己到Global
|
|
||||||
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
|
|
||||||
func get_player() -> Player:
|
|
||||||
return _cached_player
|
|
||||||
|
|
||||||
## 外部快速获取Player Controller
|
|
||||||
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)
|
|
||||||
|
|
@ -1,19 +1,12 @@
|
||||||
##TODO:清楚掉這裏和PhantomCamera相關的部分
|
|
||||||
@tool
|
@tool
|
||||||
@icon("res://addons/reedcamera/icon/camera_anchor_icon.svg")
|
@icon("uid://bsdmq0essfmpk")
|
||||||
class_name CameraAnchor extends Node2D
|
class_name CameraAnchor extends Node2D
|
||||||
|
|
||||||
const _CONSTANTS = preload("res://addons/reedcamera/_data/CameraSystemConst.gd")
|
|
||||||
|
|
||||||
@export_group("Anchor Config")
|
@export_group("Anchor Config")
|
||||||
##该priority不会直接修改Anchor的priority,只用作初始化
|
##该priority不会直接修改Anchor的priority,只用作初始化
|
||||||
@export var priority: int = 0
|
@export var priority: int = 0
|
||||||
##此Anchor是否有效
|
##此Anchor是否有效
|
||||||
@export var enabled: bool = true
|
@export var enabled: bool = true
|
||||||
## =========================
|
|
||||||
## Blend Config
|
|
||||||
## =========================
|
|
||||||
@export_subgroup("Blending")
|
|
||||||
##是否要存在相機過渡時間
|
##是否要存在相機過渡時間
|
||||||
@export var use_blend: bool = true
|
@export var use_blend: bool = true
|
||||||
##過度時間
|
##過度時間
|
||||||
|
|
@ -53,6 +46,12 @@ const _CONSTANTS = preload("res://addons/reedcamera/_data/CameraSystemConst.gd")
|
||||||
limit_right = value
|
limit_right = value
|
||||||
if Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
queue_redraw()
|
queue_redraw()
|
||||||
|
@export_subgroup("Follow")
|
||||||
|
@export var follow_player: bool = false
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var _pcam_manager: Node = null
|
||||||
|
|
||||||
## 编辑器预览面板设置
|
## 编辑器预览面板设置
|
||||||
@export_group("Editor Preview")
|
@export_group("Editor Preview")
|
||||||
|
|
@ -63,7 +62,6 @@ const _CONSTANTS = preload("res://addons/reedcamera/_data/CameraSystemConst.gd")
|
||||||
@export var limit_preview_color: Color = Color(0.9, 0.3, 0.3, 0.8)
|
@export var limit_preview_color: Color = Color(0.9, 0.3, 0.3, 0.8)
|
||||||
@export var limit_preview_line_width: float = 2.0
|
@export var limit_preview_line_width: float = 2.0
|
||||||
|
|
||||||
var _camera_global : Node = null
|
|
||||||
|
|
||||||
var _priority: int :
|
var _priority: int :
|
||||||
set(value):
|
set(value):
|
||||||
|
|
@ -77,26 +75,26 @@ func _ready() -> void:
|
||||||
if not Engine.is_editor_hint():
|
if not Engine.is_editor_hint():
|
||||||
_runtime_ready()
|
_runtime_ready()
|
||||||
|
|
||||||
func _runtime_ready() -> void:
|
|
||||||
_priority = priority
|
|
||||||
|
|
||||||
func _enter_tree() -> void:
|
func _enter_tree() -> void:
|
||||||
if not Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
pass
|
_pcam_manager = Engine.get_singleton("PhantomCameraManager")
|
||||||
#_camera_global.register_anchor(self) #只有在runtime我们才向管理器注册anchor
|
return
|
||||||
|
|
||||||
|
CameraSystem.register_anchor(self)
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
func _exit_tree() -> void:
|
||||||
if not Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
pass
|
_pcam_manager = null
|
||||||
#_camera_global.unregister_anchor(self) #只有在runtime我们才向管理器注册anchor
|
return
|
||||||
|
CameraSystem.unregister_anchor(self)
|
||||||
|
|
||||||
func _draw() -> void:
|
func _draw() -> void:
|
||||||
if not Engine.is_editor_hint():
|
if not Engine.is_editor_hint():
|
||||||
return
|
return
|
||||||
|
|
||||||
if show_camera_preview:
|
if show_camera_preview and is_instance_valid(_pcam_manager):
|
||||||
draw_rect(
|
draw_rect(
|
||||||
_camera_frame_rect_draw(),
|
_camera_frame_rect_like_phantom(),
|
||||||
preview_color,
|
preview_color,
|
||||||
false,
|
false,
|
||||||
preview_line_width
|
preview_line_width
|
||||||
|
|
@ -119,41 +117,28 @@ func _camera_limit_rect() -> Rect2:
|
||||||
|
|
||||||
return Rect2(pos, size)
|
return Rect2(pos, size)
|
||||||
|
|
||||||
func _camera_frame_rect_draw() -> Rect2:
|
func _camera_frame_rect_like_phantom() -> Rect2:
|
||||||
var cg = _get_camera_global()
|
# PhantomCamera 使用的是 manager.screen_size
|
||||||
if cg:
|
var screen_size: Vector2 = _pcam_manager.screen_size
|
||||||
var screen_size: Vector2 = cg.get_screen_size()
|
|
||||||
|
|
||||||
var z := zoom
|
var z := zoom
|
||||||
z.x = maxf(z.x, 0.001)
|
z.x = maxf(z.x, 0.001)
|
||||||
z.y = maxf(z.y, 0.001)
|
z.y = maxf(z.y, 0.001)
|
||||||
|
|
||||||
var size := Vector2(
|
var size := Vector2(
|
||||||
screen_size.x / z.x,
|
screen_size.x / z.x,
|
||||||
screen_size.y / z.y
|
screen_size.y / z.y
|
||||||
)
|
)
|
||||||
|
|
||||||
# PhantomCamera:以自身为中心
|
# PhantomCamera:以自身为中心
|
||||||
return Rect2(-size * 0.5, size)
|
return Rect2(-size * 0.5, size)
|
||||||
|
|
||||||
print("沒有找到全局相機")
|
|
||||||
return Rect2(Vector2.ZERO,Vector2.ZERO)
|
|
||||||
|
|
||||||
|
func _runtime_ready() -> void:
|
||||||
|
_priority = priority
|
||||||
|
|
||||||
##内部懶加載全局相機管理器
|
|
||||||
func _get_camera_global() -> Object:
|
|
||||||
if _camera_global:
|
|
||||||
return _camera_global
|
|
||||||
|
|
||||||
if Engine.has_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME):
|
|
||||||
_camera_global = Engine.get_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME)
|
|
||||||
|
|
||||||
return _camera_global
|
|
||||||
|
|
||||||
## 强制清空所有的camera anchor in register 然后把自己注册进去
|
|
||||||
func push_camera() -> void:
|
func push_camera() -> void:
|
||||||
_get_camera_global().clear_camera_anchors()
|
CameraSystem.reset_all_camera_priority()
|
||||||
_get_camera_global().register_anchor(self)
|
_priority = 1000
|
||||||
|
|
||||||
func pop_camera() -> void:
|
func pop_camera() -> void:
|
||||||
_get_camera_global().unregister_anchor(self)
|
_priority = 0
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[gd_scene load_steps=2 format=3 uid="uid://bflwr7cryd2l0"]
|
[gd_scene load_steps=2 format=3 uid="uid://bflwr7cryd2l0"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://dyxrydokgy0qs" path="res://addons/reedcamera/scripts/CameraAnchor.gd" id="1_1b11o"]
|
[ext_resource type="Script" uid="uid://dyxrydokgy0qs" path="res://_shared/camera/CameraAnchor.gd" id="1_dhu66"]
|
||||||
|
|
||||||
[node name="CameraAnchor" type="Node2D"]
|
[node name="CameraAnchor" type="Node2D"]
|
||||||
script = ExtResource("1_1b11o")
|
script = ExtResource("1_dhu66")
|
||||||
zoom = Vector2(0.75, 0.75)
|
use_camera_limit = true
|
||||||
|
|
@ -0,0 +1,207 @@
|
||||||
|
'''全局的相机管理器
|
||||||
|
|
||||||
|
======= 外部调用函数 =======
|
||||||
|
|
||||||
|
'''
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
@onready var camera_2d: Camera2D = %Camera2D
|
||||||
|
@onready var camera_shake_player: CameraShakePlayer = %CameraShakePlayer
|
||||||
|
|
||||||
|
var _cached_anchors: Array[CameraAnchor] = []
|
||||||
|
var _current_anchor: CameraAnchor
|
||||||
|
var _switch_tween: Tween
|
||||||
|
var _player_remote: RemoteTransform2D
|
||||||
|
var _base_camera_pos := Vector2.ZERO
|
||||||
|
|
||||||
|
##标记位,用来检测当前帧是否存在相机切换
|
||||||
|
var _switch_scheduled := false
|
||||||
|
var _dirty := false
|
||||||
|
|
||||||
|
## 玩家关卡内静态相机
|
||||||
|
const CAMERA_FOLLOWER:= preload("res://_shared/camera/camera_follower.tscn")
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
_base_camera_pos = camera_2d.global_position
|
||||||
|
|
||||||
|
func _process(delta):
|
||||||
|
if not camera_2d:
|
||||||
|
return
|
||||||
|
|
||||||
|
var shake_offset := camera_shake_player.update(delta)
|
||||||
|
camera_2d.global_position = _base_camera_pos + shake_offset
|
||||||
|
|
||||||
|
## 外部获取玩家全局相机
|
||||||
|
func get_cached_camera() -> Camera2D:
|
||||||
|
return camera_2d
|
||||||
|
|
||||||
|
## 注册一个相机锚点
|
||||||
|
func register_anchor(anchor: CameraAnchor) -> void:
|
||||||
|
if anchor in _cached_anchors:
|
||||||
|
return
|
||||||
|
_cached_anchors.append(anchor)
|
||||||
|
anchor.on_priority_change.connect(on_anchor_priority_changed)
|
||||||
|
_request_evaluate()
|
||||||
|
|
||||||
|
## 当相机锚点的权重改变时,向管理器触发事件
|
||||||
|
func on_anchor_priority_changed(priority:int, anchor: CameraAnchor) -> void:
|
||||||
|
_request_evaluate()
|
||||||
|
|
||||||
|
## 注销一个相机锚点
|
||||||
|
func unregister_anchor(anchor: CameraAnchor) -> void:
|
||||||
|
_cached_anchors.erase(anchor)
|
||||||
|
if _current_anchor == anchor:
|
||||||
|
_current_anchor = null
|
||||||
|
_request_evaluate()
|
||||||
|
|
||||||
|
func _request_evaluate() -> void:
|
||||||
|
_dirty = true
|
||||||
|
if _switch_scheduled:
|
||||||
|
return
|
||||||
|
_switch_scheduled = true
|
||||||
|
call_deferred("_commit_camera_anchor")
|
||||||
|
|
||||||
|
func _commit_camera_anchor() -> void:
|
||||||
|
_switch_scheduled = false
|
||||||
|
if not _dirty:
|
||||||
|
return
|
||||||
|
_dirty = false
|
||||||
|
|
||||||
|
# 清理无效
|
||||||
|
_cached_anchors = _cached_anchors.filter(func(a): return is_instance_valid(a))
|
||||||
|
|
||||||
|
var winner: CameraAnchor = _pick_best_anchor()
|
||||||
|
|
||||||
|
if winner == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
if winner == _current_anchor:
|
||||||
|
return
|
||||||
|
|
||||||
|
switch_anchor(winner)
|
||||||
|
|
||||||
|
func _pick_best_anchor() -> CameraAnchor:
|
||||||
|
var best: CameraAnchor = null
|
||||||
|
var best_p := -INF
|
||||||
|
|
||||||
|
for a in _cached_anchors:
|
||||||
|
if not a.enabled:
|
||||||
|
continue
|
||||||
|
if a._priority > best_p:
|
||||||
|
best_p = a._priority
|
||||||
|
best = a
|
||||||
|
|
||||||
|
return best
|
||||||
|
|
||||||
|
## 排序已有的锚点
|
||||||
|
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)
|
||||||
|
_current_anchor = a
|
||||||
|
return
|
||||||
|
|
||||||
|
## 重置所有的Camera的_priority
|
||||||
|
func reset_all_camera_priority() -> void:
|
||||||
|
for a in _cached_anchors:
|
||||||
|
a._priority = 0
|
||||||
|
|
||||||
|
##应用Anchor的Limit
|
||||||
|
func _apply_anchor_limits(anchor: CameraAnchor) -> void:
|
||||||
|
if not camera_2d:
|
||||||
|
return
|
||||||
|
camera_2d.limit_left = anchor.global_position.x + anchor.limit_left
|
||||||
|
camera_2d.limit_right = anchor.global_position.x + anchor.limit_right
|
||||||
|
camera_2d.limit_top = anchor.global_position.y + anchor.limit_top
|
||||||
|
camera_2d.limit_bottom = anchor.global_position.y + anchor.limit_bottom
|
||||||
|
|
||||||
|
func _clear_camera_limits() -> void:
|
||||||
|
if not camera_2d:
|
||||||
|
return
|
||||||
|
camera_2d.limit_left = -10000000
|
||||||
|
camera_2d.limit_right = 10000000
|
||||||
|
camera_2d.limit_top = -10000000
|
||||||
|
camera_2d.limit_bottom = 10000000
|
||||||
|
|
||||||
|
## 切换相机
|
||||||
|
func switch_anchor(target_anchor: CameraAnchor) -> void:
|
||||||
|
if target_anchor == null:
|
||||||
|
return
|
||||||
|
if target_anchor == _current_anchor:
|
||||||
|
return
|
||||||
|
if not is_instance_valid(camera_2d):
|
||||||
|
return
|
||||||
|
|
||||||
|
#优先清除已有的remote
|
||||||
|
if _player_remote:
|
||||||
|
_player_remote.queue_free()
|
||||||
|
_player_remote = null
|
||||||
|
|
||||||
|
# 中断旧 Tween
|
||||||
|
if _switch_tween and _switch_tween.is_running():
|
||||||
|
_switch_tween.kill()
|
||||||
|
_switch_tween = null
|
||||||
|
|
||||||
|
var camera := camera_2d
|
||||||
|
var blend_time : float = max(target_anchor.blend_time, 0.001)
|
||||||
|
|
||||||
|
_clear_camera_limits()
|
||||||
|
|
||||||
|
_switch_tween = get_tree().create_tween()
|
||||||
|
_switch_tween.set_ignore_time_scale(true)
|
||||||
|
_switch_tween.set_trans(Tween.TRANS_CUBIC)
|
||||||
|
_switch_tween.set_ease(Tween.EASE_OUT)
|
||||||
|
|
||||||
|
# ===== 位置 =====
|
||||||
|
_switch_tween.tween_property(
|
||||||
|
self,
|
||||||
|
"_base_camera_pos",
|
||||||
|
target_anchor.global_position,
|
||||||
|
blend_time
|
||||||
|
)
|
||||||
|
|
||||||
|
# ===== Zoom =====
|
||||||
|
_switch_tween.parallel().tween_property(
|
||||||
|
camera,
|
||||||
|
"zoom",
|
||||||
|
target_anchor.zoom,
|
||||||
|
blend_time * 1.5
|
||||||
|
)
|
||||||
|
|
||||||
|
# 完成回调
|
||||||
|
_switch_tween.finished.connect(func():
|
||||||
|
_current_anchor = target_anchor
|
||||||
|
_update_anchor_follow_state(target_anchor)
|
||||||
|
_apply_anchor_limits(target_anchor)
|
||||||
|
)
|
||||||
|
|
||||||
|
_current_anchor = target_anchor
|
||||||
|
|
||||||
|
func _update_anchor_follow_state(anchor: CameraAnchor) -> void:
|
||||||
|
# 先清理旧的 RemoteTransform
|
||||||
|
if _player_remote and is_instance_valid(_player_remote):
|
||||||
|
_player_remote.queue_free()
|
||||||
|
_player_remote = null
|
||||||
|
|
||||||
|
if not anchor.follow_player:
|
||||||
|
return
|
||||||
|
|
||||||
|
var p := GlobalEvent.get_player()
|
||||||
|
|
||||||
|
if not p or not is_instance_valid(p):
|
||||||
|
push_warning("CameraAnchor wants to follow player, but player is not registered.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 创建 RemoteTransform2D
|
||||||
|
var rt := RemoteTransform2D.new()
|
||||||
|
rt.name = "__CameraAnchorFollow"
|
||||||
|
rt.remote_path = camera_2d.get_path()
|
||||||
|
|
||||||
|
p.add_child(rt)
|
||||||
|
_player_remote = rt
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[gd_scene load_steps=3 format=3 uid="uid://b8pv5wtbo0y20"]
|
[gd_scene load_steps=3 format=3 uid="uid://b8pv5wtbo0y20"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://04mchxkp161a" path="res://_camera/CameraSystem.gd" id="1_xxnab"]
|
[ext_resource type="Script" uid="uid://04mchxkp161a" path="res://_shared/camera/CameraSystem.gd" id="1_xxnab"]
|
||||||
[ext_resource type="Script" uid="uid://sfrjes1hq8b7" path="res://_camera/camera_shake/CameraShakePlayer.gd" id="2_xxnab"]
|
[ext_resource type="Script" uid="uid://sfrjes1hq8b7" path="res://_shared/camera/camera_shake/CameraShakePlayer.gd" id="2_xxnab"]
|
||||||
|
|
||||||
[node name="CameraSystem" type="Node"]
|
[node name="CameraSystem" type="Node"]
|
||||||
script = ExtResource("1_xxnab")
|
script = ExtResource("1_xxnab")
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
extends RemoteTransform2D
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
var global_camera: Camera2D = CameraSystem.get_cached_camera()
|
||||||
|
if not global_camera:
|
||||||
|
push_error("[CameraFollower]:No Global Camera Founded")
|
||||||
|
return
|
||||||
|
remote_path = global_camera.get_path()
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene load_steps=2 format=3 uid="uid://bmb1en8itine5"]
|
[gd_scene load_steps=2 format=3 uid="uid://bmb1en8itine5"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://1xtjkoufyjlp" path="res://_camera/camera_follower.gd" id="1_8rvp5"]
|
[ext_resource type="Script" uid="uid://1xtjkoufyjlp" path="res://_shared/camera/camera_follower.gd" id="1_8rvp5"]
|
||||||
|
|
||||||
[node name="CameraFollower" type="RemoteTransform2D"]
|
[node name="CameraFollower" type="RemoteTransform2D"]
|
||||||
update_rotation = false
|
update_rotation = false
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_resource type="Resource" script_class="CameraShakePreset" load_steps=2 format=3 uid="uid://iv3hfxqm5503"]
|
[gd_resource type="Resource" script_class="CameraShakePreset" load_steps=2 format=3 uid="uid://iv3hfxqm5503"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_camera/camera_shake/CameraShakePreset.gd" id="1_mwfjy"]
|
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_shared/camera/camera_shake/CameraShakePreset.gd" id="1_mwfjy"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_mwfjy")
|
script = ExtResource("1_mwfjy")
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_resource type="Resource" script_class="CameraShakePreset" load_steps=2 format=3 uid="uid://bs3cqsp23047i"]
|
[gd_resource type="Resource" script_class="CameraShakePreset" load_steps=2 format=3 uid="uid://bs3cqsp23047i"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_camera/camera_shake/CameraShakePreset.gd" id="1_pnkiv"]
|
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_shared/camera/camera_shake/CameraShakePreset.gd" id="1_pnkiv"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_pnkiv")
|
script = ExtResource("1_pnkiv")
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_resource type="Resource" script_class="CameraShakePreset" load_steps=2 format=3 uid="uid://cs50mkt830f8r"]
|
[gd_resource type="Resource" script_class="CameraShakePreset" load_steps=2 format=3 uid="uid://cs50mkt830f8r"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_camera/camera_shake/CameraShakePreset.gd" id="1_3oq5o"]
|
[ext_resource type="Script" uid="uid://btm85tbxvjmex" path="res://_shared/camera/camera_shake/CameraShakePreset.gd" id="1_3oq5o"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_3oq5o")
|
script = ExtResource("1_3oq5o")
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
signal player_dead(player: Player)
|
||||||
|
|
||||||
|
var _cached_player_controller: PlayerController
|
||||||
|
var _cached_player: Player
|
||||||
|
|
||||||
|
## player controller進入tree會注冊自己到Global
|
||||||
|
func register_player_controller(pc: PlayerController) -> PlayerController:
|
||||||
|
if not pc: return null
|
||||||
|
|
||||||
|
_cached_player_controller = pc
|
||||||
|
return _cached_player_controller
|
||||||
|
|
||||||
|
## player進入tree會注冊自己到Global
|
||||||
|
func register_player(player: Player) -> Player:
|
||||||
|
if not player: return null
|
||||||
|
|
||||||
|
_cached_player = player
|
||||||
|
return _cached_player
|
||||||
|
|
||||||
|
## 外部快速获取Player
|
||||||
|
func get_player() -> Player:
|
||||||
|
return _cached_player
|
||||||
|
|
||||||
|
## 外部快速获取Player Controller
|
||||||
|
func get_player_controller() -> PlayerController:
|
||||||
|
return _cached_player_controller
|
||||||
|
|
||||||
|
## 外部用于监听Player死亡
|
||||||
|
func boradcast_player_dead_event(player:Player) -> void:
|
||||||
|
player_dead.emit(player)
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
@tool
|
|
||||||
extends RefCounted
|
|
||||||
|
|
||||||
#region Constants
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://bpsj1nyihan67
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
[gd_scene load_steps=3 format=3 uid="uid://b2rtcqvak066v"]
|
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://c673bap4b12fx" path="res://icon.svg" id="1_6ducv"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cw6buluknvjj" path="res://_camera/PlateformerCamera.tscn" id="2_owtx0"]
|
|
||||||
|
|
||||||
[node name="Test" type="Node2D"]
|
|
||||||
|
|
||||||
[node name="Icon" type="Sprite2D" parent="."]
|
|
||||||
position = Vector2(-1, -2)
|
|
||||||
texture = ExtResource("1_6ducv")
|
|
||||||
|
|
||||||
[node name="PlateformerCamera" parent="." instance=ExtResource("2_owtx0")]
|
|
||||||
ignore_rotation = false
|
|
||||||
position_smoothing_enabled = true
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
[gd_resource type="Resource" script_class="ReedCameraShakePreset" load_steps=2 format=3 uid="uid://wm3cmccp1ydl"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://wlqopoksgvjc" path="res://addons/reedcamera/resource/ReedCameraShakePreset.gd" id="1_8o8fw"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1_8o8fw")
|
|
||||||
amplitude = Vector2(10, 10)
|
|
||||||
frequency = 100.0
|
|
||||||
metadata/_custom_type_script = "uid://wlqopoksgvjc"
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
[plugin]
|
|
||||||
|
|
||||||
name="ReedCamera"
|
|
||||||
description="Reed zhu 製作的用於平臺跳躍類游戲的簡易Camera2D插件"
|
|
||||||
author="ReedZhu"
|
|
||||||
version=""
|
|
||||||
script="reedcamera.gd"
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
@tool
|
|
||||||
extends EditorPlugin
|
|
||||||
|
|
||||||
const REED_CAMERA_SYSTEM: StringName = "ReedCameraSystem"
|
|
||||||
|
|
||||||
func _enable_plugin() -> void:
|
|
||||||
if not Engine.has_singleton(REED_CAMERA_SYSTEM):
|
|
||||||
add_autoload_singleton(REED_CAMERA_SYSTEM, "res://addons/reedcamera/scripts/ReedCameraGlobal.gd")
|
|
||||||
|
|
||||||
|
|
||||||
func _disable_plugin() -> void:
|
|
||||||
remove_autoload_singleton(REED_CAMERA_SYSTEM)
|
|
||||||
|
|
||||||
|
|
||||||
func _enter_tree() -> void:
|
|
||||||
# Initialization of the plugin goes here.
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
|
||||||
# Clean-up of the plugin goes here.
|
|
||||||
pass
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://dqmq1t1dmsy2
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
extends RefCounted
|
|
||||||
class_name ReedCameraShakePlayer
|
|
||||||
|
|
||||||
var _preset: ReedCameraShakePreset
|
|
||||||
var _time := 0.0
|
|
||||||
var _strength := 0.0
|
|
||||||
var _active := false
|
|
||||||
|
|
||||||
var _noise := FastNoiseLite.new()
|
|
||||||
var _noise_seed := randi()
|
|
||||||
|
|
||||||
func play(preset: ReedCameraShakePreset) -> void:
|
|
||||||
_preset = preset
|
|
||||||
_time = 0.0
|
|
||||||
_strength = 0.0
|
|
||||||
_active = true
|
|
||||||
_noise.seed = _noise_seed
|
|
||||||
|
|
||||||
func stop() -> void:
|
|
||||||
_active = false
|
|
||||||
|
|
||||||
func is_active() -> bool:
|
|
||||||
return _active
|
|
||||||
|
|
||||||
func evaluate(delta: float) -> Vector2:
|
|
||||||
if not _active or not _preset:
|
|
||||||
return Vector2.ZERO
|
|
||||||
|
|
||||||
_time += delta
|
|
||||||
|
|
||||||
var total := _preset.fade_in + _preset.hold + _preset.fade_out
|
|
||||||
if _time >= total:
|
|
||||||
_active = false
|
|
||||||
return Vector2.ZERO
|
|
||||||
|
|
||||||
# ===== 强度曲线 =====
|
|
||||||
if _time < _preset.fade_in:
|
|
||||||
_strength = _time / _preset.fade_in
|
|
||||||
elif _time < _preset.fade_in + _preset.hold:
|
|
||||||
_strength = 1.0
|
|
||||||
else:
|
|
||||||
var t := (_time - _preset.fade_in - _preset.hold) / _preset.fade_out
|
|
||||||
_strength = 1.0 - t
|
|
||||||
|
|
||||||
# ===== Noise 偏移 =====
|
|
||||||
var shake_t := _time * _preset.frequency
|
|
||||||
var offset := Vector2(
|
|
||||||
_noise.get_noise_1d(shake_t),
|
|
||||||
_noise.get_noise_1d(shake_t + 1000)
|
|
||||||
)
|
|
||||||
|
|
||||||
return Vector2(
|
|
||||||
offset.x * _preset.amplitude.x,
|
|
||||||
offset.y * _preset.amplitude.y
|
|
||||||
) * _strength
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://5xuwd0cde3y8
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
# CameraShakePreset.gd
|
|
||||||
extends Resource
|
|
||||||
class_name ReedCameraShakePreset
|
|
||||||
|
|
||||||
@export var amplitude := Vector2(6, 6) # 最大位移
|
|
||||||
@export var frequency := 25.0 # 抖动频率
|
|
||||||
@export var fade_in := 0.05
|
|
||||||
@export var hold := 0.1
|
|
||||||
@export var fade_out := 0.15
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://wlqopoksgvjc
|
|
||||||
|
|
@ -1,207 +0,0 @@
|
||||||
@tool
|
|
||||||
extends Node
|
|
||||||
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
|
|
||||||
var _warned := false
|
|
||||||
|
|
||||||
var _final_offset := Vector2.ZERO
|
|
||||||
var _final_position: Vector2
|
|
||||||
var _final_zoom := Vector2.ONE
|
|
||||||
|
|
||||||
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")
|
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
|
||||||
if Engine.is_editor_hint():
|
|
||||||
return
|
|
||||||
|
|
||||||
_request_unregister()
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
if Engine.is_editor_hint():
|
|
||||||
return
|
|
||||||
|
|
||||||
if not _camera:
|
|
||||||
return
|
|
||||||
|
|
||||||
_reset_dirty_flags()
|
|
||||||
|
|
||||||
_update_final_position()
|
|
||||||
_update_camera_offset()
|
|
||||||
_update_camera_zoom()
|
|
||||||
|
|
||||||
_apply_camera_config()
|
|
||||||
|
|
||||||
func _reset_dirty_flags() -> void:
|
|
||||||
_pos_dirty = false
|
|
||||||
_offset_dirty = false
|
|
||||||
_zoom_dirty = false
|
|
||||||
|
|
||||||
func _update_final_position():
|
|
||||||
for child in get_children():
|
|
||||||
if child is CameraToolBasic \
|
|
||||||
and child.enabled \
|
|
||||||
and child.affect_position \
|
|
||||||
and child.has_base_position():
|
|
||||||
_final_position = child.get_base_position()
|
|
||||||
_pos_dirty = true
|
|
||||||
return
|
|
||||||
|
|
||||||
# fallback
|
|
||||||
_final_position = _camera.global_position
|
|
||||||
|
|
||||||
func _update_camera_offset():
|
|
||||||
var offset := Vector2.ZERO
|
|
||||||
var used := false
|
|
||||||
|
|
||||||
for child in get_children():
|
|
||||||
if child is CameraToolBasic \
|
|
||||||
and child.enabled \
|
|
||||||
and child.affect_offset \
|
|
||||||
and child.has_camera_offset():
|
|
||||||
offset += child.get_camera_offset()
|
|
||||||
used = true
|
|
||||||
|
|
||||||
_final_offset = offset
|
|
||||||
_offset_dirty = used
|
|
||||||
|
|
||||||
func _update_camera_zoom():
|
|
||||||
for child in get_children():
|
|
||||||
if child is CameraToolBasic \
|
|
||||||
and child.enabled \
|
|
||||||
and child.affect_zoom \
|
|
||||||
and child.has_camera_zoom():
|
|
||||||
_final_zoom = child.get_camera_zoom()
|
|
||||||
_zoom_dirty = true
|
|
||||||
return
|
|
||||||
|
|
||||||
# fallback
|
|
||||||
_final_zoom = _camera.zoom
|
|
||||||
|
|
||||||
func _apply_camera_config():
|
|
||||||
if _pos_dirty:
|
|
||||||
_camera.global_position = _final_position
|
|
||||||
|
|
||||||
if _offset_dirty:
|
|
||||||
_camera.offset = _final_offset
|
|
||||||
|
|
||||||
if _zoom_dirty:
|
|
||||||
_camera.zoom = _final_zoom
|
|
||||||
|
|
||||||
|
|
||||||
func _notification(what: int) -> void:
|
|
||||||
if not Engine.is_editor_hint():
|
|
||||||
return
|
|
||||||
|
|
||||||
match what:
|
|
||||||
NOTIFICATION_PARENTED, NOTIFICATION_UNPARENTED:
|
|
||||||
#print("重設parent")
|
|
||||||
call_deferred("_editor_verify")
|
|
||||||
|
|
||||||
## 編輯器層面的通過性驗證
|
|
||||||
func _editor_verify() -> void:
|
|
||||||
_camera = _find_camera()
|
|
||||||
_editor_valid = _camera != null
|
|
||||||
#print(_editor_valid)
|
|
||||||
|
|
||||||
if not _editor_valid:
|
|
||||||
_emit_config_warning()
|
|
||||||
else:
|
|
||||||
_warned = false
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if Engine.is_editor_hint():
|
|
||||||
return
|
|
||||||
|
|
||||||
if not _camera:
|
|
||||||
_camera = _find_camera()
|
|
||||||
|
|
||||||
_request_register()
|
|
||||||
|
|
||||||
func _find_camera() -> Camera2D:
|
|
||||||
var p := get_parent()
|
|
||||||
return p as Camera2D if p is Camera2D else null
|
|
||||||
|
|
||||||
func _request_register() -> void:
|
|
||||||
var sys := Engine.get_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME)
|
|
||||||
if not sys:
|
|
||||||
return
|
|
||||||
|
|
||||||
_runtime_registered = sys.request_register_pointer(self)
|
|
||||||
|
|
||||||
func _request_unregister() -> void:
|
|
||||||
if not _runtime_registered:
|
|
||||||
return
|
|
||||||
|
|
||||||
var sys := Engine.get_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME)
|
|
||||||
if sys:
|
|
||||||
sys.request_unregister_pointer(self)
|
|
||||||
|
|
||||||
_runtime_registered = false
|
|
||||||
|
|
||||||
func _emit_config_warning() -> void:
|
|
||||||
if not Engine.is_editor_hint():
|
|
||||||
return
|
|
||||||
|
|
||||||
if _warned:
|
|
||||||
return
|
|
||||||
|
|
||||||
push_warning(
|
|
||||||
"[CameraPointer] Invalid configuration: parent node must be Camera2D. "
|
|
||||||
+ "Current parent: %s" % (get_parent() if get_parent() else "null")
|
|
||||||
)
|
|
||||||
|
|
||||||
_warned = true
|
|
||||||
|
|
||||||
## =========================
|
|
||||||
## Public API
|
|
||||||
## =========================
|
|
||||||
##获取相机
|
|
||||||
func get_camera() -> Camera2D:
|
|
||||||
if not _camera:
|
|
||||||
_camera = _find_camera()
|
|
||||||
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_tool_by_type(type:ToolType) -> Node:
|
|
||||||
return get_tool(type_script_map.get(type))
|
|
||||||
|
|
||||||
##获取所有工具
|
|
||||||
func get_tools() -> Array[CameraToolBasic]:
|
|
||||||
var out: Array[CameraToolBasic] = []
|
|
||||||
for c in get_children():
|
|
||||||
if c is CameraToolBasic:
|
|
||||||
out.append(c)
|
|
||||||
return out
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://py4h5jxlncro
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
@tool
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
const _CONSTANTS = preload("res://addons/reedcamera/_data/CameraSystemConst.gd")
|
|
||||||
|
|
||||||
var _screen_size : Vector2i
|
|
||||||
|
|
||||||
var _camera_points : Array[CameraPointer]
|
|
||||||
var _current_camera_point : CameraPointer
|
|
||||||
|
|
||||||
|
|
||||||
signal anchors_changed
|
|
||||||
|
|
||||||
var _anchors : Array[CameraAnchor]
|
|
||||||
|
|
||||||
#region 相機指針
|
|
||||||
func request_register_pointer(ptr: CameraPointer) -> bool:
|
|
||||||
if not is_instance_valid(ptr):
|
|
||||||
return false
|
|
||||||
|
|
||||||
var cam := ptr.get_camera()
|
|
||||||
if not is_instance_valid(cam):
|
|
||||||
return false # System 决定:无效 camera 不接受注册
|
|
||||||
|
|
||||||
# 去重
|
|
||||||
if ptr in _camera_points:
|
|
||||||
_current_camera_point = ptr
|
|
||||||
return true
|
|
||||||
|
|
||||||
_camera_points.append(ptr)
|
|
||||||
|
|
||||||
# 你可以在这里做选择策略:比如最新优先/priority
|
|
||||||
_current_camera_point = ptr
|
|
||||||
return true
|
|
||||||
|
|
||||||
func request_unregister_pointer(ptr: CameraPointer) -> void:
|
|
||||||
_camera_points.erase(ptr)
|
|
||||||
if _current_camera_point == ptr:
|
|
||||||
_current_camera_point = _camera_points.back() if _camera_points.size() > 0 else null
|
|
||||||
|
|
||||||
func get_current_camera_pointer() -> CameraPointer:
|
|
||||||
return _current_camera_point
|
|
||||||
|
|
||||||
func get_camera() -> Camera2D:
|
|
||||||
return _current_camera_point.get_camera() if _current_camera_point else null
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 相機錨點
|
|
||||||
func register_anchor(anchor: CameraAnchor) -> void:
|
|
||||||
if anchor in _anchors:
|
|
||||||
return
|
|
||||||
|
|
||||||
_anchors.append(anchor)
|
|
||||||
|
|
||||||
# 监听 anchor 内部变化
|
|
||||||
anchor.on_priority_change.connect(_on_anchor_priority_changed)
|
|
||||||
|
|
||||||
anchors_changed.emit()
|
|
||||||
|
|
||||||
func unregister_anchor(anchor: CameraAnchor) -> void:
|
|
||||||
if anchor in _anchors:
|
|
||||||
_anchors.erase(anchor)
|
|
||||||
|
|
||||||
if anchor.on_priority_change.is_connected(_on_anchor_priority_changed):
|
|
||||||
anchor.on_priority_change.disconnect(_on_anchor_priority_changed)
|
|
||||||
|
|
||||||
anchors_changed.emit()
|
|
||||||
|
|
||||||
func _on_anchor_priority_changed(_p: int, _a: CameraAnchor) -> void:
|
|
||||||
anchors_changed.emit()
|
|
||||||
|
|
||||||
func get_all_anchors() -> Array[CameraAnchor]:
|
|
||||||
return _anchors.duplicate()
|
|
||||||
|
|
||||||
func clear_camera_anchors() -> void:
|
|
||||||
_anchors.clear()
|
|
||||||
anchors_changed.emit()
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
func _enter_tree() -> void:
|
|
||||||
if not Engine.has_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME):
|
|
||||||
Engine.register_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME, self)
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
# Setting default screensize
|
|
||||||
_screen_size = Vector2i(
|
|
||||||
ProjectSettings.get_setting("display/window/size/viewport_width"),
|
|
||||||
ProjectSettings.get_setting("display/window/size/viewport_height")
|
|
||||||
)
|
|
||||||
|
|
||||||
# For editor
|
|
||||||
if Engine.is_editor_hint():
|
|
||||||
ProjectSettings.settings_changed.connect(func():
|
|
||||||
_screen_size = Vector2i(
|
|
||||||
ProjectSettings.get_setting("display/window/size/viewport_width"),
|
|
||||||
ProjectSettings.get_setting("display/window/size/viewport_height")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# For runtime
|
|
||||||
else:
|
|
||||||
get_tree().get_root().size_changed.connect(func():
|
|
||||||
_screen_size = get_viewport().get_visible_rect().size
|
|
||||||
)
|
|
||||||
|
|
||||||
func get_screen_size() -> Vector2i:
|
|
||||||
return _screen_size
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://dqtfis2553nhn
|
|
||||||
|
|
@ -1,114 +0,0 @@
|
||||||
@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)
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://dckyyfvj25bxf
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
extends CameraToolBasic
|
|
||||||
class_name ReedCameraAnchorController
|
|
||||||
|
|
||||||
const _CONSTANTS = preload("res://addons/reedcamera/_data/CameraSystemConst.gd")
|
|
||||||
## =========================
|
|
||||||
## Private
|
|
||||||
## =========================
|
|
||||||
var _anchors: Array[CameraAnchor] = []
|
|
||||||
var _current_anchor: CameraAnchor
|
|
||||||
var _current_position := Vector2.ZERO
|
|
||||||
var _current_zoom := Vector2.ONE
|
|
||||||
var _tween: Tween
|
|
||||||
|
|
||||||
## =========================
|
|
||||||
## Config
|
|
||||||
## =========================
|
|
||||||
@export var move_duration := 0.4
|
|
||||||
@export var ease_type := Tween.EASE_OUT
|
|
||||||
@export var trans_type := Tween.TRANS_CUBIC
|
|
||||||
|
|
||||||
var _evaluate_requested := false
|
|
||||||
var _evaluate_scheduled := false
|
|
||||||
|
|
||||||
var _sys : Object = null
|
|
||||||
|
|
||||||
enum AnchorState {
|
|
||||||
IDLE,
|
|
||||||
TRANSITIONING,
|
|
||||||
}
|
|
||||||
|
|
||||||
var _state := AnchorState.IDLE
|
|
||||||
|
|
||||||
## =========================
|
|
||||||
## Lifecycle
|
|
||||||
## =========================
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
_anchors = _get_camera_system().get_all_anchors()
|
|
||||||
|
|
||||||
_get_camera_system().anchors_changed.connect(_on_anchors_changed)
|
|
||||||
|
|
||||||
_request_evaluate()
|
|
||||||
|
|
||||||
func _on_anchors_changed() -> void:
|
|
||||||
_sync_anchors()
|
|
||||||
_request_evaluate()
|
|
||||||
|
|
||||||
func _sync_anchors() -> void:
|
|
||||||
_anchors = _get_camera_system().get_all_anchors()
|
|
||||||
|
|
||||||
func _request_evaluate() -> void:
|
|
||||||
_evaluate_requested = true
|
|
||||||
|
|
||||||
if _evaluate_scheduled:
|
|
||||||
return
|
|
||||||
|
|
||||||
_evaluate_scheduled = true
|
|
||||||
call_deferred("_commit_evaluate")
|
|
||||||
|
|
||||||
func _commit_evaluate() -> void:
|
|
||||||
_evaluate_scheduled = false
|
|
||||||
|
|
||||||
if not _evaluate_requested:
|
|
||||||
return
|
|
||||||
|
|
||||||
_evaluate_requested = false
|
|
||||||
_evaluate_impl()
|
|
||||||
|
|
||||||
func _evaluate_impl() -> void:
|
|
||||||
var winner := _pick_best_anchor()
|
|
||||||
if winner == _current_anchor:
|
|
||||||
return
|
|
||||||
|
|
||||||
_switch_to(winner)
|
|
||||||
|
|
||||||
func _pick_best_anchor() -> CameraAnchor:
|
|
||||||
var best: CameraAnchor
|
|
||||||
var best_p := -INF
|
|
||||||
|
|
||||||
for a in _anchors:
|
|
||||||
if not a.enabled:
|
|
||||||
continue
|
|
||||||
if a.priority > best_p:
|
|
||||||
best = a
|
|
||||||
best_p = a.priority
|
|
||||||
|
|
||||||
return best
|
|
||||||
|
|
||||||
func _switch_to(anchor: CameraAnchor) -> void:
|
|
||||||
if not anchor:
|
|
||||||
return
|
|
||||||
|
|
||||||
_current_anchor = anchor
|
|
||||||
_state = AnchorState.TRANSITIONING
|
|
||||||
|
|
||||||
var target := anchor.global_position
|
|
||||||
var target_zoom := anchor.zoom if (anchor.zoom.x > 0 and anchor.zoom.y > 0) else Vector2.ONE
|
|
||||||
|
|
||||||
if _tween and _tween.is_running():
|
|
||||||
_tween.kill()
|
|
||||||
|
|
||||||
if not anchor.use_blend or anchor.blend_time <= 0.0:
|
|
||||||
_current_position = target
|
|
||||||
_current_zoom = target_zoom
|
|
||||||
_state = AnchorState.IDLE
|
|
||||||
return
|
|
||||||
|
|
||||||
_tween = get_tree().create_tween()
|
|
||||||
_tween.set_ignore_time_scale(true)
|
|
||||||
_tween.set_trans(trans_type)
|
|
||||||
_tween.set_ease(ease_type)
|
|
||||||
|
|
||||||
_tween.tween_property(self, "_current_position", target, anchor.blend_time)
|
|
||||||
_tween.parallel().tween_property(self, "_current_zoom", target_zoom, anchor.blend_time)
|
|
||||||
|
|
||||||
_tween.finished.connect(func():
|
|
||||||
_state = AnchorState.IDLE
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
## =========================
|
|
||||||
## CameraPointer Interface
|
|
||||||
## =========================
|
|
||||||
func get_base_position() -> Vector2:
|
|
||||||
if _state != AnchorState.TRANSITIONING:
|
|
||||||
return Vector2.ZERO
|
|
||||||
return _current_position
|
|
||||||
|
|
||||||
func has_base_position() -> bool:
|
|
||||||
return _state == AnchorState.TRANSITIONING
|
|
||||||
|
|
||||||
func get_camera_zoom() -> Vector2:
|
|
||||||
if _state != AnchorState.TRANSITIONING:
|
|
||||||
return Vector2.ONE
|
|
||||||
return _current_zoom
|
|
||||||
|
|
||||||
func has_camera_zoom() -> bool:
|
|
||||||
return _state == AnchorState.TRANSITIONING
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://bhl5it46hv4n2
|
|
||||||
|
|
@ -1,191 +0,0 @@
|
||||||
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 : 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 _final_position: Vector2
|
|
||||||
|
|
||||||
##缓存全局系统
|
|
||||||
var _sys: Object = null
|
|
||||||
##缓存DebugTool
|
|
||||||
var _screen_ratio_rect_draw_tool: Node = null
|
|
||||||
##缓存camera
|
|
||||||
var _camera: Camera2D = null
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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_system() -> Object:
|
|
||||||
if _sys:
|
|
||||||
return _sys
|
|
||||||
|
|
||||||
if Engine.has_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME):
|
|
||||||
_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
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://wl83yn33gu3m
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
@tool
|
|
||||||
extends CameraToolBasic
|
|
||||||
class_name ReedCameraShakeController
|
|
||||||
## =========================
|
|
||||||
## Runtime
|
|
||||||
## =========================
|
|
||||||
|
|
||||||
var _players: Array[ReedCameraShakePlayer] = []
|
|
||||||
var _current_offset := Vector2.ZERO
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
if Engine.is_editor_hint():
|
|
||||||
return
|
|
||||||
|
|
||||||
set_process(true)
|
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
|
||||||
_players.clear()
|
|
||||||
_current_offset = Vector2.ZERO
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
if Engine.is_editor_hint():
|
|
||||||
return
|
|
||||||
|
|
||||||
if not enabled:
|
|
||||||
_current_offset = Vector2.ZERO
|
|
||||||
return
|
|
||||||
|
|
||||||
var offset := Vector2.ZERO
|
|
||||||
|
|
||||||
for p in _players:
|
|
||||||
offset += p.evaluate(delta)
|
|
||||||
|
|
||||||
# 移除已经结束的 player
|
|
||||||
_players = _players.filter(func(p): return p.is_active())
|
|
||||||
|
|
||||||
_current_offset = offset
|
|
||||||
|
|
||||||
## =========================
|
|
||||||
## Public API
|
|
||||||
## =========================
|
|
||||||
func play_shake(preset: ReedCameraShakePreset) -> void:
|
|
||||||
if not preset:
|
|
||||||
return
|
|
||||||
|
|
||||||
var player := ReedCameraShakePlayer.new()
|
|
||||||
player.play(preset)
|
|
||||||
_players.append(player)
|
|
||||||
|
|
||||||
func stop_all() -> void:
|
|
||||||
for p in _players:
|
|
||||||
p.stop()
|
|
||||||
_players.clear()
|
|
||||||
_current_offset = Vector2.ZERO
|
|
||||||
|
|
||||||
## =========================
|
|
||||||
## Pipeline Output
|
|
||||||
## =========================
|
|
||||||
|
|
||||||
func get_camera_offset() -> Vector2:
|
|
||||||
return _current_offset
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://dwr1s51svvank
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
@abstract
|
|
||||||
class_name CameraToolBasic
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
## =========================
|
|
||||||
## Participation Flags
|
|
||||||
## =========================
|
|
||||||
@export var enabled: bool = true
|
|
||||||
|
|
||||||
@export var affect_position: bool = false
|
|
||||||
@export var affect_offset: bool = false
|
|
||||||
@export var affect_zoom: bool = false
|
|
||||||
|
|
||||||
## =========================
|
|
||||||
## Interfaces(子类选择性实现)
|
|
||||||
## =========================
|
|
||||||
func get_base_position() -> Vector2:
|
|
||||||
return Vector2.ZERO
|
|
||||||
|
|
||||||
func has_base_position() -> bool:
|
|
||||||
return false
|
|
||||||
|
|
||||||
func get_camera_offset() -> Vector2:
|
|
||||||
return Vector2.ZERO
|
|
||||||
|
|
||||||
func has_camera_offset() -> bool:
|
|
||||||
return false
|
|
||||||
|
|
||||||
func get_camera_zoom() ->Vector2:
|
|
||||||
return Vector2.ONE
|
|
||||||
|
|
||||||
func has_camera_zoom() -> bool:
|
|
||||||
return false
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://bwj5j7hr5ucm3
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
[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")
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
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)
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://cwxwsfl1mx7kc
|
|
||||||
|
|
@ -10,17 +10,17 @@ config_version=5
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="godot-plateformer"
|
config/name="PhantomAgnes"
|
||||||
run/main_scene="uid://3vc8ojbiyy5w"
|
run/main_scene="uid://3vc8ojbiyy5w"
|
||||||
config/features=PackedStringArray("4.5", "Forward Plus")
|
config/features=PackedStringArray("4.5", "Forward Plus")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
[autoload]
|
[autoload]
|
||||||
|
|
||||||
GlobalEvent="*res://_shared/GlobalEvent.gd"
|
CameraSystem="*res://_shared/camera/CameraSystem.tscn"
|
||||||
|
GlobalEvent="*res://_shared/global_event.gd"
|
||||||
ReedVFX="*res://addons/reedfx/vfx/ReedVFXSystem.tscn"
|
ReedVFX="*res://addons/reedfx/vfx/ReedVFXSystem.tscn"
|
||||||
ReedSceneRegistry="*res://addons/reedscene/scene/SceneRegistry.gd"
|
ReedSceneRegistry="*res://addons/reedscene/scene/SceneRegistry.gd"
|
||||||
ReedCameraSystem="*res://addons/reedcamera/scripts/ReedCameraGlobal.gd"
|
|
||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ window/stretch/mode="canvas_items"
|
||||||
|
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
enabled=PackedStringArray("res://addons/reedcamera/plugin.cfg", "res://addons/reedcomponent/plugin.cfg", "res://addons/reedfx/plugin.cfg", "res://addons/reedinput/plugin.cfg", "res://addons/reedscene/plugin.cfg")
|
enabled=PackedStringArray("res://addons/reedcomponent/plugin.cfg", "res://addons/reedfx/plugin.cfg", "res://addons/reedinput/plugin.cfg", "res://addons/reedscene/plugin.cfg")
|
||||||
|
|
||||||
[file_customization]
|
[file_customization]
|
||||||
|
|
||||||
|
|
@ -42,8 +42,9 @@ folder_colors={
|
||||||
|
|
||||||
[global_group]
|
[global_group]
|
||||||
|
|
||||||
|
ROOM="房间分组,其下存在所有的Room"
|
||||||
PLAYER="玩家分组,其下只存在玩家控制器"
|
PLAYER="玩家分组,其下只存在玩家控制器"
|
||||||
GRAPABLE="進入該分組的Collision視爲可以被玩家抓握"
|
GRAPABLE=""
|
||||||
PLAYER_RESPAWN="所有的PlayerRespawnPoint的绑定Group"
|
PLAYER_RESPAWN="所有的PlayerRespawnPoint的绑定Group"
|
||||||
ROCK_BREAK="Can break fragile rock."
|
ROCK_BREAK="Can break fragile rock."
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue