Permanently change Class variables with keyPress

Hello all! This might be better suited in the beginners coding support because I feel like complete noob for not figuring this out :stuck_out_tongue:

I want my character in the game to spawn an object when I press “e”, but only one!
I first just tried to instantiate self.equipped = None, then set it to 1 when I press “e”. Ofc the problem is that the variable changes back to None when i release the button.
So I realized I need an if statement that will always be true to keep self.equipped at 1.

Something like:

If e and not self.equipped:
addObj(“thing”, self)
If “thing” in self.children:
self.equipped = 1

Now equipped always stays at 1 after I’ve pressed the hotkey, but it still adds objects!
I wrote print(scene.objects) at the end and even though equipped stays at 1 it just keeps adding 10 obj/second…
I might just still be really confused with classes and their proper structure and execution. But how would you solve this?
Feels like there should be a way to tell my code to keep self.equipped at 1 until I tell it to change…

If you don’t understand my problem then I can send a blend later. :stuck_out_tongue:
Thanks in advance

Hi Emilime,

If you have an if statement that is always true you don’t need it, so you can remove it. You’re problem is that self.equipped is some where set to None, each time. Where in you’re class do you instantiate self.equipped to None?
You must do this in the constructor of the class in the init function.

Hey Petege, thanks for answering!

Unfortunately I can’t provide a blend atm, but either way it’s a big incohesive mess…
I do set self.equipped to None in the init function! Because the player starts of unequipped. Basically my code looks like this(in pseudo):

Class PlayerClass:

Def init:
<Bunch of variables like move speed etc>
self.equipped = 0

Def movement:
<Here I handle movement and physics>

Def main:
Self.movement() #call this function

In here is where I experiment:

If e:
scene.addObject(“obj”, self)
self.equipped = 1

(Here self.equipped changes to 1 but only for the duration I hold ‘e’. I realize now that maybe my problem is that im using a INPUT_ACTIVE instead of INPUT_JUST_ACTIVATED? Or maybe that doesn’t matter and equipped will still reset to 0, but after only 1 tic… i dont know.)

#Outside the class
player = PlayerClass() # instantiate the class
player.main()

I’m trying to explain it better but I might’ve just confused you more xD I’m not so good with words…

But basically it’s like you said: I instantiate equipped as 0. Then I want it to switch when I press a button, and go back to 0 when I press another.

Thanks

Hi Emilime,

The problem is that the players class is created over and over again and that resets every time the variable self.equipped to 0.

The player variable of player = PlayerClass() must be a global variable and you need to check if class is instantiated or not. You can do that in this way:

if player is None:
    player = PlayerClass()

Hmmm, yeah you’re right, sounds like constant reincarnation of the class could be the problem…
The example you give, is it the same as “if not init in self: init = 1” that I’ve seen in some people write? Or is it different…? I’ll try it anyway :slight_smile:
I read on some forum though that class variables (the ones I define in the init function?) is a better solution and alternative than using global variables… and some of their examples even look like mine and they claim it works!
“If it is in the class instance, will it maintain the list items?”
“Yes, that is the point.”

Class variables are the ones you write in the init function… right? Man this is confusing xD sry, but tanks for your help ^^

The “if player is None” here is not the same as “if not init in self: init = 1”. The problem, in the Blender game engine mode, is that the class is created each time new (without the if) and the old one gone and each time the init of a new instance is called.
The old one is gone so all class variable are new ones.

The scope of variables must be so small as possible. If it is not necessary to make it global don’t do it, but here the variable player must be global, it must be stay “forever”.
When the reference to the player class is in that variable no new player class is created (therefore the if statement: if player is None) and all class variables are then persistent.

Class variables are the variables in the class.
Blender runs, in the game engine mode, each frame through the script. In a “normal” program you don’t have this problem, the player is then created ones.