Changes to variable not persisiting after function call
Asked Answered
E

6

0

Hello,

I have a function in my code to apply damage to the health of a creature. However, the changes to the current_creature_health variable do not persist outside of the function, when it is called again it begins from the creatures maximum health rather than the damaged health from the previous call.

I've managed to strip away all but the offending lines of code that still repeat the issue. Normally the function would only be called once elsewhere in code, but here the function is called repeatedly in Process and prints the following output.

To my eyes the function should call repeatedly until its in the negative and just keep going. but it keeps starting again from the max health stored in the resource. Plugging the stats directly into the function does work as intended, but defeats the point of having a reusable function.

Any ideas?

extends Node3D
@export var creature : creature_resource # Resource that contains Creature Stats
var current_health : int # Variable to store health

func _ready():
        current_health = creature.health() # Assign health the Variable (87)

func _process(delta):	
	damage_func(current_health) 

func damage_func(health):
	var damage_hp = 25 # Fixed value in place of damage calculation
	print("defender_health B: %d" % health)	# Health before Damage
	health -= damage_hp # Subtract from HP
	print("defender_health A: %d \n =====" % health) # Health After Damage

Output:
defender_health B: 87
defender_health A: 62
defender_health B: 87
defender_health A: 62

Exhalant answered 29/2 at 19:55 Comment(0)
S
0

Exhalant Basic types like ints or floats are assigned and passed by value, not by reference.

Staffan answered 29/2 at 20:13 Comment(0)
E
0

Staffan
Thanks for your reply, but you will have to explain it a little more. I've spent a little time googleing 'passed by value, pass by reference' and I'm a little wiser from it, but still somewhat lost on whats wrong here.

Exhalant answered 29/2 at 20:46 Comment(0)
H
0

Pass by value means you make a copy of the variable when you call the function. Any changes to the copy inside the function do not affect the value of the original variable you used as argument when calling the function.

Harpoon answered 29/2 at 20:51 Comment(0)
F
0

Harpoon I noticed the variable in your header is a different name than in the functions? Was that an error or copied wrong?

A variable is a reference. The health is repeating because that variable is a reference to "87" up top. So you say "health" and the code assumes you are saying 87. It's usually best to make a separate variable for this because then you have a separate value to reference - and hence, update the code. I recommend using one variable as MAX health and then another as current, then alter the current. That way you're not constantly referencing that 87.

So something like:

extends Node3D
@export var creature : creature_resource # Resource that contains Creature Stats
var max_health : int # variable for max health (or const if you're not changing it)
var current_health : int  # variable for current health, changes over time

func _ready():
        max_health = creature.health() # Assign health to max
        current_health = max_health # pull value from max and update

func _process(delta):
        damage_func(current_health)

func damage_func(health):
        var damage_hp = 25 # Fixed value in place of damage calculation
        print("defender_health B: %d" % health) # Health before Damage
        health-=damage_hp # Subtract from HP, Prevents damage form going negative
        print("defender_health A: %d \n =====" % health) # Health After Damage

P.S.
To post the code correctly, use three (~) symbols start and end, like this (minus the hashes of course):

##~~~
##your code here
##~~~
Frances answered 2/3 at 1:18 Comment(0)
E
0

Frances
Your right, It was an error in copying out the code to here, just like my comment mentioning 'Prevents damage form going negative' when I didn't have the max() function in there to stop it going lower than zero.

Thankyou for your help, I've made the required changes and all is working again now.

func hello world():
     print("got it !")
Exhalant answered 2/3 at 21:18 Comment(0)
S
0

Frances That won't work. You're assuming the integral type is passed by reference which is not the case. Your example will have exactly the same problem as OP's. Passing local properties to methods is redundant (and confusing) anyway as all class methods already have the direct access to all class properties

The proper way to do it would be:

extends Node

@onready var max_health: int = 1000
@onready var health: int = max_health

func _process(delta):
	damage(10)

func damage(amount):
	print("Health before damage: ", health)
	health -= amount
	print("Health after damage: ", health, "\n")
Staffan answered 2/3 at 23:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.