how do i update a argument from a function properly?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By random_developer

I’m new to godot and english isn’t my language…

Through the _dano() function and using arguments, I’m trying to update the enemy’s health variable in case the player hit the attack, but instead of him taking life in each attack, he takes only once and is no longer updated.

for example, the enemy’s health is 10 HP, if I do an attack of 1 HP of damage it will only be at 9, and no matter how many times I do the attack again, it will stay at 9 HP. But when I change the argument of the variable to the variable itself inside the function, it normally updates.

how do I update the variable properly using arguments in the function?

note: the variable in question is global

Global variable:

var vida_base = 10

the function updates normally when:

 func _input(event):
    _dano(alvo, "hitbox", 1, 2)
  #when a collision occurs, if it is a specific enemy and you did an attack, it will cause a certain amount of damage to him

 func _dano(nome, nome_alvo, dano, dano2):	
    if colisao:
        if ataque1 == true:
            if nome == nome_alvo:
		        Global.vida_base -= dano
		        Global.dano = true
	    if ataque2 == true:
		    if nome == nome_alvo:
		        Global.vida_base -= dano2
		        Global.dano = true

the function updates wrong when:

func _input(event):
    _dano(alvo, Global.vida_base, "hitbox", 1, 2)

#when a collision occurs, if it is a specific enemy and you did an attack, it will cause a certain amount of damage to him

func _dano(nome, vida, nome_alvo, dano, dano2):	
    if colisao:
        if ataque1 == true:
            if nome == nome_alvo:
		        vida -= dano
		        Global.dano = true
	    if ataque2 == true:
		    if nome == nome_alvo:
		        vida -= dano2
		        Global.dano = true

all player script:

var ataque1 = false
var rec_ataque1 = false

var ataque2 = false
var rec_ataque2 = false

var colisao = false

var alvo = "none"

func _ready():
    _get_input()

#player's control

func _get_input():
    if Input.is_action_just_pressed("ataque1") and rec_ataque1 == true:
	    ataque1 = true
	    rec_ataque1 = false
    else:
	    ataque1 = false

    if Input.is_action_pressed("ataque2") and rec_ataque2 == true:
	    ataque2 = true
	    rec_ataque2 = false
    else:
	    ataque2 = false

# with each key pressed, the function is activated

func _input(event):
    _get_input()
    _dano(alvo, Global.vida_base, "hitbox", 1, 2)

#when a collision occurs, if it is a specific enemy and you did an attack, it will cause a certain amount of damage to him

func _dano(nome, vida, nome_alvo, dano, dano2):	
    if colisao:
        if ataque1 == true:
            if nome == nome_alvo:
		        vida -= dano
		        Global.dano = true
	    if ataque2 == true:
		    if nome == nome_alvo:
		        vida -= dano2
		        Global.dano = true

#checks the name of the collided target

func _on_area_de_dano_area_entered(area):
    colisao = true
    alvo = area.name
:bust_in_silhouette: Reply From: SteveSmith

When you pass an int argument to a function, it passes a copy of that int. So in your second example, you’re passing a copy of Global.vida_base. So Global.vida_base is never actually changed, only the copy is. This copy is discarded when the function ends.

Thanks for the answer, it helped me to understand why it wasn’t working and more of how arguments work. But, is there a way to specify to the function that the variable itself has to be changed, not the copy of it?

random_developer | 2022-11-15 19:35

Unfortunately Godot doesn’t have anything like the byref keyword that some languages have. However, there might be ways around it, described in these answers: https://forum.godotengine.org/32684/how-do-i-pass-variables-by-reference-to-functions

SteveSmith | 2022-11-16 08:38