Blender Game Engine Trials and Tribulations

Struggles and Solutions in my quest to implement a somewhat complicated game with the Blender Game Engine.

Tuesday, May 09, 2006

Global Varible in the Blender Game Engine

So, I didn't quite make "tomorrow" with this post, but better late than never. I've actually decided that the Blender physics engine is not predictable enough for what I need to do, and I've decided to try using some of the great gaming libraries available for C# to roll my own. I have a bunch of Blender tips I still want to get out, though, so I'll keep posting stuff here for a while.

A lot of head scratching has led to a number of Blender realizations. First is that I discovered the Blender API reference here, and it took me quite a while to realize that the GameLogic API, which you need to do anything related to the sensors and actuators, is here. In a completely separate page. Wish I had caught that one a litte earlier.

I spent a long time poking around trying to find example of mouse input in a Blender game, but came up largely empty handed. I found this tutorial, and this thread which convinced me that Blender could handle things of the complexity I was shooting for. That was nice, but I still didn't understand exactly how to get scripts to run, say, once. I could get them to run "always" but not once, when the game starts up.

It turns out, you really can't. Or at least, you don't. You just let scripts run "always" and then cross your fingers that things run smoothly enough. You could try to use global variables to get things to run once, but global variables don't persist across "frames" of "always".

In fact, there is only one way to get global variables to work in the game engine that I found. You need to store them in the GameLogic object, which persists. Like so:
  GameLogic.yourvar = "your value"
Unfortunately, if you put a statement like that in your "always" script, it'll run over and over, re-initializing your variable in every frame. And it's not exactly a "variable" if it stays constant now, is it?

So, you'd think you could do something like:
  if  not GameLogic.yourvar:
GameLogic.yourvar = "your value"
But that doesn't work either. You get an error when you try to use GameLogic.yourvar without initializing it. What you have to do instead is a little more circuitous:
  try:
GameLogic.yourvar
except AttributeError:
GameLogic.yourvar = None

if not GameLogic.yourvar == None:
GameLogic.yourvar = "your value"
And that, my friend, is the way you get some code to run once, and only once. You set a global variable called runonce, in the method explained above, and then if it's unset you run your code.

What a hack. Now you can see why I wanted to bail out of Blender.

4 Comments:

  • At 11:32 AM, Anonymous Anonymous said…

    In fact, you can set script in GameBlender to run once. Use sensor "Always" and un-check pulse mode (button on the left side of sensor block).

    On global variables: Method I use for initialization of global variables is:
    if hasattr(GameLogic, 'myGlobVar') == 0:
    GameLogic.myGlobVar = 'my global variable'

     
  • At 4:35 AM, Anonymous Anonymous said…

    the hasattr method definitly is the right way to proceed ...

     
  • At 11:24 AM, Anonymous Anonymous said…

    If you have code you only want to do one job in the scene then stop; attach the script to an empty. Set the empty's logic sensor to 'always' and have it feed in to a 'python script controller' then tie in an 'end object actuator'. Write what you want it to do and after the job is complete end the empty and the script will no longer run.

     
  • At 6:05 PM, Anonymous Anonymous said…

    thanks, the first to comment. closing the pulse solve my problem

     

Post a Comment

<< Home