godot-plateformer/addons/reedcomponent/grap_hook/spawn_hook_component.gd

102 lines
3.1 KiB
GDScript3
Raw Normal View History

2025-12-29 11:54:31 +08:00
class_name SpawnHookComponet extends ComponentBase
##SpawnHookComponent必须绑定一个相关的RayCast2D用来控制射线想要检测的位置。
@export var binded_hook_ray_cast_2d : RayCast2D
##可以通過在這裏添加一個ComponentOwner默認的字段名來讀取輸入方向默認是為空的。
@export var binded_hook_move_input_property_name: StringName
##用於Grapping Hook的基本Instance
const GRAPPING_HOOK = preload("uid://wlbuqjf2rg03")
var _ray_direction: Vector2
var _ray_reference: RayCast2D
var _ray_length: float = 100
##當前的Graphook的實例
var _current_grap_hook_inst: GrappingHook
##钩爪伸长达到动画位置
signal hook_reach_finished
func _physics_process(delta: float) -> void:
#更新當前的grap_hook的移動
update_grap_physics(get_grap_move_input(),delta)
##用来设置绑定的Ray的方向。
func set_ray_direction(in_direction: Vector2) -> Vector2:
if _ray_direction == in_direction:
return _ray_direction
_ray_direction = in_direction
if _ray_reference:
_ray_reference.target_position = Vector2(
_ray_direction.x,
_ray_direction.y
) * _ray_length
return _ray_direction
##生成一个Grap Hook
func spawn_grap_hook_inst() -> GrappingHook:
##如果沒有正確的和任何可以抓取的物體發生碰撞,會直接返回
if not _ray_reference.is_colliding(): return null
var i = GRAPPING_HOOK.instantiate() as GrappingHook
i.init(self)
get_tree().current_scene.add_child(i)
i.start_hook_with_instigator(_ray_reference.get_collision_point(),component_owner)
_current_grap_hook_inst = i
return _current_grap_hook_inst
func grap_reach_target(duration: float) -> bool:
if not _ray_reference or not _current_grap_hook_inst:return false
##重置所有Points的坐标点位置。
_current_grap_hook_inst.reset_line_points_to_target(component_owner.global_position)
var start_pos: Vector2 = component_owner.global_position
var target_pos: Vector2 = _ray_reference.get_collision_point()
var t := get_tree().create_tween()
t.set_trans(Tween.TRANS_SINE)
t.set_ease(Tween.EASE_OUT)
t.tween_method(
_current_grap_hook_inst.update_line_anchor_pos,
start_pos,
target_pos,
duration
)
##结束时会发送广播
t.finished.connect(_on_hook_reach_finished)
return true
##更新GrapHook的物理
func update_grap_physics(input: Vector2,delta: float) -> void:
if input.is_zero_approx(): return
if not _current_grap_hook_inst: return
var i = input.normalized()
_current_grap_hook_inst.move_hook(input,delta)
##此函數默認為Vector.Zeor,子類可以重寫以得到一個全新的結果,也可以通過綁定的方式獲得一個結果。
func get_grap_move_input() -> Vector2:
#如果我們在組件裏綁定了Component上的一個字段也可以直接獲取。
if binded_hook_move_input_property_name in component_owner:
return component_owner.get(binded_hook_move_input_property_name)
return Vector2.ZERO
func _on_hook_reach_finished() -> void:
_current_grap_hook_inst.m_update_rope_with_nodes = true
hook_reach_finished.emit()
func _init_component() -> void:
_ray_reference = binded_hook_ray_cast_2d