Global Variable Issue

Hello, so here’s my issue; I have 3 global variables that I’m using to hold the values for the colour of a laser point. This is so you can customize the laser colour from the options menu. This works, except when you go back into the menu it resets the colour to its default value.

The variables in question are: logic.LaserRed, logic.laserGreen, logic.LaserBlue

Here is the code on the menu for setting these variables:

from bge import render, logic

scene = logic.getCurrentScene()
cont = logic.getCurrentController()

render.showMouse (1)    

RedOB = scene.objects ["LaserColorRed"] 
GreenOB = scene.objects ["LaserColorGreen"]
BlueOB = scene.objects ["LaserColorBlue"]

RedOB.getPropertyNames;
GreenOB.getPropertyNames;
BlueOB.getPropertyNames;

logic.LaserRed = RedOB ["RedAmount"]
logic.LaserGreen = GreenOB ["GreenAmount"]
logic.LaserBlue = BlueOB ["BlueAmount"]

logic.LaserRed = (logic.LaserRed / 1000)
logic.LaserGreen = (logic.LaserGreen / 1000)
logic.LaserBlue = (logic.LaserBlue /1000)

RedOB ["RedAmount"] = (logic.LaserRed / 1000)
GreenOB ["GreenAmount"] = (logic.LaserGreen / 1000)
BlueOB ["BlueAmount"] = (logic.LaserBlue /1000)

I would really appreciate it if someone could figure this out for me.

YOu can do math and other things in the same line just so you know, so you could replace:

 logic.LaserRed = RedOB ["RedAmount"]
logic.LaserGreen = GreenOB ["GreenAmount"]
logic.LaserBlue = BlueOB ["BlueAmount"]

logic.LaserRed = (logic.LaserRed / 1000)
logic.LaserGreen = (logic.LaserGreen / 1000)
logic.LaserBlue = (logic.LaserBlue /1000)

with:

logic.LaserRed = RedOB ["RedAmount"]/1000
logic.LaserGreen = GreenOB ["GreenAmount"]/1000
logic.LaserBlue = BlueOB ["BlueAmount"]/1000

As for your problem, I suspect it’s beacuse global variables only stay for the current “game” wich means they vanish if you use “start game from file” or “set scene”
It think.

Thank you for replying, this in not exactly what I need, would it help if you could see the blend file?

A. I will do this it will be helpful:)

B. I will switch the mouse cursor to only become visible once. (I only have this in there because its not visible on the main scene)

C. I’m not sure why. (In the menu I have 3 objects I’m using as sliders to control the laser colour RedOB is one of them.)

D. I will remove that Line of code.

E. This Calls the 3 objects that are being used for sliders

RedOB = scene.objects ["LaserColorRed"] 
GreenOB = scene.objects ["LaserColorGreen"]
BlueOB = scene.objects ["LaserColorBlue"]

This calls the properties from these three objects

RedOB.getPropertyNames;
GreenOB.getPropertyNames;
BlueOB.getPropertyNames;

This sets the Global variables

logic.LaserRed = RedOB ["RedAmount"]
logic.LaserGreen = GreenOB ["GreenAmount"]
logic.LaserBlue = BlueOB ["BlueAmount"]

This makes the variables small enough to fit in a float variable that I’m using for the colour.

logic.LaserRed = (logic.LaserRed / 1000)
logic.LaserGreen = (logic.LaserGreen / 1000)
logic.LaserBlue = (logic.LaserBlue /1000)

This is how I think my code works, without the last 3 lines it does works to change the colour, but as soon as I go back into the menu the colour resets to black.

F. I’m new to python coding so I’m not sure how to define a class, help would really be appreciated.

Let me know it you want to see the .blend

Thank you for the help so far:)

I think it goes black because of:


RedOB ["RedAmount"] = (logic.LaserRed / 1000)
GreenOB ["GreenAmount"] = (logic.LaserGreen / 1000)
BlueOB ["BlueAmount"] = (logic.LaserBlue /1000)

I think you mean this:


RedOB ["RedAmount"] = (logic.LaserRed * 1000)
GreenOB ["GreenAmount"] = (logic.LaserGreen * 1000)
BlueOB ["BlueAmount"] = (logic.LaserBlue *1000)

you were right, that code is what I men’t to do, but I still have the same problem.

Here is the .blend, I got rid of as much as I could without getting errors, to make it a smaller file. The script that is the issue is called “MenuSettings” and is activated on the “Menu Scene”

If you go into play mode, you hit the ESC key to go to the menu for the game, but if you hit the ESC key again it resumes the game. So when your in the menu you can click on the gray box in the top right corner, or hit “p” on the keyboard to esc.

[ATTACH]178373[/ATTACH]

Hi Kevin,

I looked at your file.
It is really nice that you named all the logic bricks. It makes it much easier to read the logic.
Unfortunately it is still quite complex. A good reason to updated the BGE Analyzer.

The problem you have is that you make the LaserColorSide* the primary source for the color value.

This happens:
MenuBackground is always running “MenuSettings”:
-> the properties of the LaserColorSlider are after scene loading always set to default (black)

When you remove the scene your loose the LaserColorSliders with their current values.
When you load the Menu scene again. New LaserColorSliders are created again with default values.

This code always replaces your “global” variable with the properties from the LaserColorSliders as long as they exist.

Design proposal:
I think this is a design issue.

Think about following:
A) where should the laser color be read
B) where should the laser color be write
C) where should the laser color reside

Each of these are complete separate tasks. They only interconnection is the laser color itself.

lets play with it:
A)
I guess one or more lasers should use read the laser color.
Question: when to read it?
Do you want the laser color be displayed at the Menu scene (as a preview)?
Maybe you want to store the laser color to disk? Which means a saveLoader needs to read it.

You see there are multiple game objects which want to read the laser color. This is a one-to-many relationship.

B)
Each single laserColorSlider sets the laser color.
Maybe you want preset buttons?
What about numerical input (text fields)?
Should a saveLoader write the LaserColor which read it from disk?

Again we have a one-to-many relationship on writing.
The number of readers and the number of writers does not need to be the same.

C)
Where to place the laserColor?
If you answer A) with “Only one laser!” this laser would be a good place. But the laser might be disappear and the laserColor with it.
Currently the laserColor resides at the LaserColorSliders. When they disappear the laserColor disapperas too. This is what you have now.

You tried to place the laserColor at Gamelogic (bge.logic is an alias of GameLogic). This is quite a good idea as this module will remain until the game ends. But it is not a natural place for it. There is no relationship between laserColor and GameLogic.
You can leave it there or place it:

  • at an game object that remains throughout the game run (e.g. an object in the main scene). Switching scenes might be a problem.
  • at a python module specifically for this purpose (as mentioned earlier)
  • in a container which is placed at a Module or a game object. A container can be a dictionary (e.g. globalDict)

Regardless where you store the laserColor. You need exactly one storage that should be the primary source.
Readers A) can read this storage.
Writers B) can modify this storage.

You just need to decide WHEN they do that.

A natural time is readers read the storage after a writer modified the storage.

writer -> storage -> reader, reader, … reader

This is quite easy to do. You already have such a concept: Messages.
Please read the BGE guide to Messages. If you read this you might have notified that your slider logic fits pretty well into the health bar logic.

But the slider is not the health bar, it is the value provider. The storage is the health bar. It does not need to be visible.

Recommendation:
I recommend to do following:
LaserColorSlider:

  • on creation it reads it’s property values from the storage (currently it remains at the default value)
  • on using (animation) it writes the current property values to the storage (as you already do)
  • after using it sends a message “laserColor changed” to ALL objects. If there is a reader it can refresh after receiving this message.

Laser:

  • on creation it reads the storage and colors its mesh
  • on receiving “laserColor changed” it does exactly the same.

Alternative processing:
You can let the storage send the update message rather then the writer. If the storage is no active game object it can’t do anything (GameLogic is passive). So you would need a “control” object which performs the update notification.

I hope you are not to confused
It is much text right now.

Btw. If you start from menu scene Blender crashes on Esc.

This is because on Esc the Menu scene gets removed without an alternative.

I suggest to add an Scene Actuator to add Main as background scene.

There is no problem if you already come from the Main scene. if the scene is already present it will not be added again.

Thank you for the help I will try this and let you know if i can get it to work, and thank you for telling me this :slight_smile: I was just using the p key as an alternative for exiting but I will fix this too :slight_smile:

With some Minor changes to my script and, realizing that had the “tap” option on, on one of my logic bricks, I have gotten this to work.:slight_smile: thank you everybody to all the help :), I really, really appreciate all the help.:slight_smile: