extends LimboState @onready var root: Normal = %Normal @export_category("Hook Pull Release") ##如果和目标点小于此距离,则会自动松开 @export var release_distance: float = 12.0 ##如果钩爪方向和角色速度方向小于此,则中断 @export var release_dot_threshold: float = 0.0 ##最短pull时间,即使距离非常近,也会判断至少此时间 @export var min_pull_timer: float = 0.08 ##如果钩爪跳时速度低于这个值,则会强制重置跳跃 @export var force_jump_reset_maxinum_speed: float = 230 var _pull_timer := 0.0 var _anchor var _tween: Tween func _setup() -> void: self.add_event_handler(&"trigger_jump",_handle_trigger_jump) func _enter() -> void: var tween := get_tree().create_tween() tween.set_ignore_time_scale(true) tween.tween_property(Engine, "time_scale", .25, .03) tween.tween_interval(.1) tween.tween_property(Engine, "time_scale", 1.0, .05) var hook_inst: Hook = agent.spawn_hook_comp.get_current_hook_inst() if hook_inst: var i = hook_inst.get_direction_id() if i >= 0: var csp : CameraShakePreset = null if i == 0 or i == 4: csp = agent.camera_shake_preset.get("y_only_light") elif i == 1 or i == 5: csp = agent.camera_shake_preset.get("xy_light") elif i == 2 or i == 6: csp = agent.camera_shake_preset.get("x_only_light") elif i == 3 or i == 7: csp = agent.camera_shake_preset.get("xy_light") #if csp: #CameraSystem.camera_shake_player.play(csp) if root.grap_hook_state._jump_grace_timer > 0: _hook_to_jump() _pull_timer = 0.0 _anchor = agent.spawn_hook_comp.get_current_hook_anchor() if _anchor and is_instance_valid(_anchor): agent.locomotion_comp._custom_move_to(_anchor) func _update(delta: float) -> void: _pull_timer += delta if _pull_timer < min_pull_timer: return if not _anchor or not is_instance_valid(_anchor): _force_release() return var character : CharacterBody2D = agent var pos: Vector2 = character.global_position var target_pos: Vector2 = _anchor.global_position var to_target := target_pos - pos var distance := to_target.length() if distance <= release_distance: _force_release() return if distance > 0.001: var dir := to_target / distance if character.velocity.dot(dir) <= release_dot_threshold: _force_release() return func _exit() -> void: agent.locomotion_comp._release_hook_keep_momentum() agent.spawn_hook_comp.release_cached_hook() func _handle_trigger_jump() -> bool: _hook_to_jump() return false func _hook_to_jump() -> void: var v : float = agent.velocity.length() if v <= force_jump_reset_maxinum_speed: get_root().blackboard.set_var(&"force_reset_jump",true) get_root().blackboard.set_var(&"want_to_jump",true) self.dispatch(&"hook_to_jump") func _force_release() -> void: agent.locomotion_comp.stop_custom_move(false) if agent.spawn_hook_comp.has_method("release_hook"): agent.spawn_hook_comp.release_hook() ##解除hook if agent.is_on_floor(): self.dispatch(&"exit_on_ground") else: self.dispatch(&"exit_on_air") return