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