The problem is the else statement. Lets say you have two vines, vine1 and vine2 in that order in your scene tree. The _physics_process will run vine1 first, then vine2. If you could vine with vine1, it will set your player variables. Then vine2 will unset them. If you could vine with vine2, vine1 will unset them but vine2 will set them. If you had five vines, only the last one will ever work.
Remove your else statement first.
#Checks for LOS but only when inside area
func _physics_process(delta: float) -> void:
if (abs(Global.player.position.x - position.x) < 32) and (Global.player.position.y - position.y < 120) and LOScheck():
Global.player.current_vine = self
Global.player.can_vine = true
# Remove the else statement below
# else:
# Global.player.current_vine = null
# Global.player.can_vine = false
vinesprite.set_point_position(1, to_local(Global.player.position))
if Global.player.state == Global.player.States.vine:
vinesprite.visible=true
else:
vinesprite.visible=false
Now you can detect when you can vine. It will be the player that now checks when you cannot vine. So in your player script, add this somewhere (like in your _process or _physics process):
# Check first we can vine and not currently vining:
if can_vine and not states.vine:
# check can still vine and re-use your LOScheck function from the vine
if not (
(abs(current_vine.position.x - position.x) < 32) and
(current_vine.position.y - position.y < 120) and
current_vine.LOScheck()
):
current_vine = false
can_vine = false
That should work.
The only thing I would raise here is that doing it the way you are doing it means you can never have vines too close together. I donât know if you want vines close together, or how the vines are activated (does the player hit a button to swing or climb?). The way I might do this is to have a vine detector area on my player. When a vine is in reach, ie vine entered area, update the active vine in your current_vine. When area is exited, set it to null. If you make your check area directly up like a tall thin capsule shape, you can have vines very near each other too. (You may not need your LOScheck at all then depending on your other game mechanics).
Anyway, I hope that helps in some way.
PS current_vine should be set to null, not false.
var current_vine: StaticBody2D = null
In fact all you really need to do is just keep current_vine, and the flag is superfluous.
if is_instance_valid(current_vine):
would do the same thing as:
if can_vine: