I have a boolen that change to false by itself each frame then back to true

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

Hi guys,

I am new to game engine in general and I am not sure what I am doing wrong. I tried to debug it myself so I used the print command to see where the issue was and I noticed that the variable start at “false” which is what I want and when the condition is met it will change the variable to “true” which is also what I want. The issue is after the condition is met for the first time the variable change to false every other frame but I don’t have any line that will change it to “false”.

Related part from the code:

extends KinematicBody2D
    
var movePlayer = Vector2()
var throwSpear = Vector2()
var playerOnSpear
var spearPicked

func _init():
	
	playerOnSpear = false
	spearPicked = false
	
	pass


func _physics_process(_delta):
	
	_player_movment()
	
	_pickup_spear()
	
	print("SP: ", spearPicked, " POS: ", playerOnSpear)
	
	#_throw()
	
	pass


func _pickup_spear():
	if playerOnSpear && Input.is_action_pressed("ui_accept"):
		spearPicked = true

func _on_PickUp_Area_body_entered(body):
	if body.get_name() == "KinematicBody2D":
		playerOnSpear = true
	
	pass

full code:

    extends KinematicBody2D

const UP = Vector2(0,-1)
const SPEED = 400
const GRAVITY = 20
const JUMP_FORCE = -1000

#var Rigidbody2D = get_world_2d().get_node("Spear")

var movePlayer = Vector2()
var throwSpear = Vector2()
var playerOnSpear
var spearPicked

func _init():
	
	playerOnSpear = false
	spearPicked = false
	
	pass


func _physics_process(_delta):
	
	_player_movment()
	
	_pickup_spear()
	
	print("SP: ", spearPicked, " POS: ", playerOnSpear)
	
	#_throw()
	
	pass


func _player_movment():
	movePlayer.y += GRAVITY
	
	if Input.is_action_pressed("ui_right"):
		movePlayer.x = SPEED
	elif Input.is_action_pressed("ui_left"):
		movePlayer.x = -SPEED
	else:
		movePlayer.x = 0
	
	if is_on_floor() && Input.is_action_just_pressed("ui_up"):
		movePlayer.y = JUMP_FORCE
	
	movePlayer = move_and_slide(movePlayer,UP)
	
	pass


#func _throw():
#	if Input.is_action_pressed("ui_accept") && playerOnSpear:
#		spearPicked = false
#
#	pass


func _pickup_spear():
	if playerOnSpear && Input.is_action_pressed("ui_accept"):
		spearPicked = true


func _on_PickUp_Area_body_entered(body):
	if body.get_name() == "KinematicBody2D":
		playerOnSpear = true
	
	pass


#func _on_PickUp_Area_body_exited(body):
	#if body.get_name() == "KinematicBody2D":
		#playerOnSpear = false

so in short, I don’t know why my variable switch between true and false instead of
staying at true. is this how it should work? should i change the logic?

Your help is appreciated.

:bust_in_silhouette: Reply From: sleepy.otter

Have you tried to print inside your _init function to see if it gets initialized at every frame ?

I would also recommend to use _ready instead of _init

Edit : url

thank you for the tips.

As you recomneded please find the results.

print inside _ready:
relust inside ready: SP: False POS: False
relust inside ready: SP: False POS: False

print after condition is met:
SP: False POS: False
SP: False POS: True
SP: False POS: False
SP: False POS: True
SP: False POS: False
SP: False POS: True
SP: False POS: False

just in case see the changes below:

func _ready():
	
	playerOnSpear = false
	spearPicked = false
	
	print("relust inside ready: ", "SP: ", spearPicked, " POS: ", playerOnSpear )
	pass

the strange thing is that the _ready() is printing twice. is this how it should have worked? or maybe it is related to some option the project setting i am not sure as to why. please tell me if you have any idea.

also what is the difference between _ready() and _init()

appreciate that you are taking from your time to read this.

Naster | 2020-12-22 17:16

_ready gets called when your node enters a scene. Check out the doc here : https://docs.godotengine.org/en/stable/classes/class_node.html#class-node-method-ready

I am still new to Godot so i don’t know why you are having this bug, but i can tell you how to think about it

Ask yourself, what could modify a variable ? For me it could be an instantiation or setting it directly

So what causes an instantiation ? Do you create a new node each time and then a new script ? Are you having the same script used by multiples nodes ? Are variables shared between nodes ? What’s the best use case to initialize a variable ?

About the setter, are you using the correct syntax ? Is it assigned locally to your function but not globally to your class ? etc…

And to answers these questions look at the doc and examples turorial
For example look at the godot documentation about GDScript, i am sure it could help
https://docs.godotengine.org/en/stable/getting_started/scripting/gdscript/gdscript_basics.html
Look also at existing project to see how they set their variables and learn from it.

About the best use case to initialize a variable, what happen if you remove

spearPicked = false

from _init and _ready, and only use it at the variable declaration like so ?

var spearPicked = false

About _ready being called twice, does it mean you are doing multiple new node or is it a normal behaviour ?

Those are ways to explore

sleepy.otter | 2020-12-22 18:40

Thank you for the tips. I will take a look at the links and will try to play around some more to find the issue. I am not facing this with other variables though and I don’t think it is a bug in the engine, mostly it is from me.

if worst come to worst I will just try different logic.

thank you for the help.

Naster | 2020-12-22 20:22

Probably way too late for the original poster but if anyone is having the same issue I think you can solve it by making the var static that at least worked for me

Bad code example below

Static var dying = false

When i do this it does not change back to false from true

Note that by making it static, the variable does ‘belong’ to the class, not the instance. That means, that when you update it, it is updated for all instances of the class (see GDScript reference — Godot Engine (stable) documentation in English).

I don’t know your code, but I would guess that dying should be a per-instance state. In this case, setting it to static is not the right solution. It might work if there is ever only one instance, but the variable changing unexpectedly suggest that there is a problem somewhere else.