69 lines
1.8 KiB
GDScript
69 lines
1.8 KiB
GDScript
class_name ClimbComponent extends ComponentBase
|
|
|
|
var characterbody: CharacterBody2D
|
|
|
|
@export var climb_max_stamina: float
|
|
@export var climb_max_speed_upward: float = 45.0
|
|
@export var climb_max_speed_downward: float = 80.0
|
|
@export var climb_acceleration: float = 900.0
|
|
|
|
|
|
var _climb_input: float
|
|
var _can_climb: bool = false
|
|
|
|
func _init_component()-> void:
|
|
characterbody = component_owner as CharacterBody2D
|
|
assert(characterbody,"组件没有正确的绑定CharacterBody2D")
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if not _can_climb: return
|
|
|
|
print("攀爬更新中")
|
|
_update_climb(delta)
|
|
characterbody.move_and_slide() #移动更新
|
|
|
|
func _update_climb(delta) -> void:
|
|
|
|
var target_abs: float
|
|
|
|
#更新目标速度
|
|
if sign(_climb_input) == .0:
|
|
target_abs = 0
|
|
elif sign(_climb_input) > 0:
|
|
target_abs = climb_max_speed_downward
|
|
else:
|
|
target_abs = climb_max_speed_upward
|
|
|
|
var target = target_abs * _climb_input
|
|
characterbody.velocity.y = speed_approach(characterbody.velocity.y,target,climb_acceleration * delta)
|
|
|
|
func add_climb_input(input: float) -> bool:
|
|
_climb_input = input
|
|
return true
|
|
|
|
func start_climb(force_reset: bool = false) -> void:
|
|
if force_reset:
|
|
characterbody.velocity = Vector2.ZERO
|
|
characterbody.move_and_slide()
|
|
|
|
_can_climb = true
|
|
|
|
func suspend_climb() -> void:
|
|
_can_climb = false
|
|
|
|
#region Helper Function
|
|
func speed_approach(current: float, target: float, delta: float) -> float:
|
|
if current < target:
|
|
return min(current + delta, target)
|
|
elif current > target:
|
|
return max(current - delta, target)
|
|
return target
|
|
|
|
func velocity_approach(current: Vector2, target: Vector2, delta: float) -> Vector2:
|
|
var result = current
|
|
result.x = speed_approach(current.x, target.x, delta)
|
|
result.y = speed_approach(current.y, target.y, delta)
|
|
return result
|
|
#endregion
|