I saw a lot of confusion regarding the use of references and names of GameObject.
Especially people not familiar with programming often mix them and wonder why the resulting behavior is not as expected. Unfortunately the BGE API supports this confusion pretty well.
In this thread I want to explain
- how to get rid of this confusion and
- how to gain a deeper understanding of the Blender Game Engine (BGE).
I hope you can find something useful.
The examples in the following text will be compatible with 2.4x and 2.5x.
What are GameObjects?
What exactly they are is not documented very well. I will not try create a complete definition. Basically they allow you to access the objects you see in your active scenes.
GameObjects are objects from type KX_GameObjects.
I assume KX stays for Ketsij which is the project name of the GameEngine.
You can see this type with
import GameLogic obj = GameLogic.getCurrentController().owner print(type(obj))
References to GameObjects
Whenever you see an object from type KX_GameObject you know this object is a GameObject. To be more specific it is a reference to a GameObject. The GameObject itself is stored somewhere in the BGE. You get a reference to it’s Python representation.
With a reference you can identify, access and manipulate the GameObject.
Names of GameObjects
The name of an GameObject is
- an attribute of the GameObject
- is a string
- is not necessarily unique
- is read-only
Especially the last fact seems to confuse people. In all of the case they want to change the name because they mixed references and names. It is really not necessary to change the name.
What is the problem?
[INDENT]GameObjects are not identified by name. [/INDENT]
When you do print() it shows you the name of the GameObject. It is much easier to read than a cryptic identificator (e.g 23746237). [If you really want to know the id use id(GameObject)].
The BGE allows you to find objects by name via scene.objects[“objectname”].
It returns ONE object (if any).
But it ignores the fact there can be MULTIPLE objects with the same name. It just returns any of them and you can’t tell which one.
I think It would be better to return a list of objects as this code does
objectsNamedCube = [obj for obj in scene.objects if obj.name == "Cube"]
or if it is a function with a well choosen name:
anyObjectNamedCube = scene.anyObject("Cube") # do not try - this function does not exist ;)
How to solve the confusion?
Just remember it!
- Prefer to store references rather than names (as long as the GameObjects live)
- Use objects[“object name”] with care … better avoid it
- Avoid the usage of hard-coded object names in Python code. The name of the object might change during development.
- All sensors return the reference to the sensed object. Not just a name.
- The names you enter at actuators (e.g. AddObject) are immediately converted to GameObject references.
- Actuators do not look for other objects with the same name after a referenced object does not exist anymore. They do not even know the name of the previous object.
print(<KX_GameObject>) = KX_GameObject.name
scene.objects[<object’s name>] = any KX_GameObject with that name
These facts let you easily confuse GameObject’s references with GameObject’s names.
[INDENT]Names are not GameObjects!
Names are not unique!