Vector2 does not get added to object position

Godot Version

4.2.1

Question

So I’m making an ability system and currently working on the second ability although I am having some trouble with the ability objects global positioning. The ability system works by the player picking up an object that determines the players current ability. So i have created a general script that sets most of the rules for how the abilities should work and a another scene that the first script instantiates.

Ability1 script:

extends Player_State

@export var ground_state : Player_State
@export var Usable_ability_node : String = "Usable_ability"
@export var run_animation_node : String = "Run"
#-------------------------------------------
@onready var cooldown_timer: Timer = $Cooldow_ability1
#-------------------------------------------
# current ability
func on_enter():
	var ability1 = character.current_ability1.instantiate()
	cooldown_timer.set_wait_time(ability1.cooldown_time)
	cooldown_timer.start()
	character.add_sibling(ability1) # Adds to same parent as player
	print("Ability added: ", ability1)
	ability1.global_position = (character.global_position) + ability1.self_offset * character.latest_direction
	print(character.global_position)
	if character.latest_direction < 1:
		ability1.scale.x = -1
	else:
		ability1.scale.x = 1
#-------------------------------------------
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
	pass
#-------------------------------------------
func _on_animation_tree_animation_finished(anim_name):
	if anim_name == Usable_ability_node:
		playback.travel(run_animation_node)
		next_state = ground_state

Air_blast script (the ability I’m working on):

extends Area2D 
#Air blast script
#-------------------------------------------
@export var damage : int = 10
@export var Hit_effect_animation : String = "Hit_effect"
@export var self_offset = Vector2(0,-25)
#------------------------------------------
@onready var anim_player = $AnimationPlayer

#sets the wait time for the cooldown timer in the player scene
var cooldown_time: int = 3
var direction = null
#-------------------------------------------
func _ready():
	direction = get_tree().get_first_node_in_group("Player_body").latest_direction
	monitoring = false
	if anim_player:
		anim_player.play("Air_blast")
#-------------------------------------------
func _process(delta):
	if anim_player.current_animation == "Air_blast":
		self.global_position.x += (direction * 500 * delta) 
#-------------------------------------------
func _on_body_entered(body):
	for child in body.get_children():
		if child is damageable:
			child.hit(damage)
			print_debug(body.name + " took " + str(damage))
	anim_player.play("Hit_effect")
#-------------------------------------------
func _on_animation_player_animation_finished(anim_name):
	if anim_name == Hit_effect_animation:
		self.queue_free()

The Issue I’m having is that the abilities self_offset dosen’t get added to the global_position when the player is facing to the left for some reason. And I don’t know why

Any and all help is appreciated :slight_smile:

How is latest_direction set? If it’s zero then this line will evaluate to a + 0

character.global_position + ability1.self_offset * character.latest_direction

Your self_offset is 25 pixels up, if it was multiplied by a negative number it would shift 25 pixels down, which seems strange to me.

1 Like

Sorry for the late reply.
latest_direction is just a variable that i use to help certain aspects (like turning around or keeping track of direction when the player is standing still) and is pretty much defined as

if direction.x != 0:
    latest_direction = direction.x
Your self_offset is 25 pixels up, if it was multiplied by a negative number it would shift 25 pixels down, which seems strange to me.

yeah i need to change that. The self offset is set at 25 pixels up so that the ability spawns at the middle of the player instead of at the feet

What is the issue? What are you expecting to happen versus what is really happening?

1 Like

Well when the player is looking right (direction/latest_direction = 1) the ability spawns where it should be, but when looking the opposite direction it spawns at the feet of the player whereas it should spawn in middle of the player (as if shooting out of)

I think you were right in that the issue is that the self_offset is multiplied by latest_direction. The reason for this is that i have another ability (an explosion that happens at a set distance) where the self_offset is set at vector2(150,0) so that it spawns at the left or right side of the player dependent on the latest_direction

The issue that I’m facing is writing the position part of the code in such a way that it accomodates any and all abilities starting position.

While writing the answer to your question I think I realised the solution that I instead of writing 1 catch all line of code i could split it into two line so as to avoid multiplying any y-values with the direction

ability1.global_position.x = (character.global_position.x) + ability1.self_offset.x * character.latest_direction
ability1.global_position.y = character.global_position.y + ability1.self_offset.y

´
You are my hero!!
Thank you for identifying the issue. This would have taken me the rest of the week if not :))

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.