Godot Version
Godot 4.2.1
Question
Im making a grapple-up your way kinda game. I have used a character with characterbody2d. the player has a grapple mechanic node on him. the grapple manager code , uses a ray cast 2d to check for surrounding collisions and if it matches a valid surface , when the player clicks grapple button , he grapples to it. The problem im facing is that , someitmes , whilst falling and trying to latch on to a valid surface , the player grapples on to empty air. idk the exact reason behind this bug. The image shows the bug.
THE CODE :
@onready var player : CharacterBody2D = get_parent()
@onready var ray : RayCast2D = $RayCast2D
@onready var launched = false
@onready var target : Vector2
@onready var rope = $Line2D
@export var rest_len = 2.0
@export var stiffness = 10.0
@export var damping = 2.0
@onready var hook = $"../GrappleHook"
func _ready():
Input.mouse_mode = Input.MOUSE_MODE_HIDDEN
func _process(delta):
hook.global_position = get_global_mouse_position()
if ray.is_colliding():
hook.modulate = "6fffbbb5"
else:
hook.modulate = "ffffffd9"
ray.look_at(get_global_mouse_position())
if Input.is_action_just_pressed("GRAB"):
if ray.is_colliding():
launch()
if Input.is_action_just_released("GRAB"):
retract()
if launched:
handle_grapple()
func launch():
if ray.is_colliding():
target = ray.get_collision_point()
if target:
launched = true
rope.show()
func retract():
launched = false
rope.hide()
func handle_grapple():
if target :
var target_dir = player.global_position.direction_to(target)
var target_dist = player.global_position.distance_to(target)
var displacement = target_dist - rest_len
var Force = Vector2.ZERO
if displacement > 0:
update_rope()
var spring_force_magnitude = stiffness * displacement
var spring_force = target_dir * spring_force_magnitude
var vel_dot = player.velocity.dot(target_dir)
var damping = -damping * vel_dot * target_dir
Force = spring_force + damping
player.velocity += Force
func update_rope():
rope.set_point_position(1,to_local(target))