0
$\begingroup$

This script intends to show the differences in changing a GameObject property directly...

obj["prop"] = value

And indirectly, it is, with a shortening / variable previously defined...

prop = obj["prop"]
prop = value

The point is: the change works directly, but not indirectly. Why does it happen?

import bge

def main(cont):

    # Basic
    own = cont.owner

    # Sensors
    key = cont.sensors["key"].positive # Keyboard sensor

    # Props
    direct = own["direct"] # If process prop directly (bool)
    prop = own["prop"] # The prop (int, float or timer)

    ############################
    ######## INITIALIZE ########
    ############################

    # Add value to prop directly. It works, showing in debug properties
    if key and direct:
        own["prop"] += 1

    # Add value to prop indirectly (through reference). It doesn't work,
    # as shown in debug properties or through print in console
    elif key and not direct:
        prop += 1
        print(prop)
$\endgroup$
0
$\begingroup$

... shorten a GameObject property into a variable?

what do you mean with shorten?

Game Object Properties

A property consists at least of a property name and a property value (it has an owner too). Within the BGE you do not have direct access to a game object property. Therefore a property is no object to be used. What you can get is the property's value.

You get the value by key access:

value = gameObject["property name"]

or

value = gameObject.get("property name")

The goal is to get the value. After getting the value the property name is usually not of further interest unless you want to change the property.

Write access means you assign a new value:

gameObject["property name"] = newValue

If the property did not exist before it adds a new one, otherwise it replaces the value.

This way the game object behaves like a dictionary, with property names as keyword and property values as values.

Your question

obj["prop"] = value

These is (as described above) a write access to the property with name "prop". It assigns the object referred by variable value as property value.

prop = obj["prop"] 
prop = value

This creates a variable named prop and assigns the value read from property named "prop". The second line creates a new variable named propassigning the object referred by variable value. The variable of the first line is gone (life time ended).

Investigation

I guess you think you can manipulate properties without using the write access. This is not possible. You can manipulate the value (which is an object) but assigning a new value has to be an write operation.

Example:

Lets assume you have a property called "amount". The value is 5.

gameObject["amount"] = 5

At a later stage you want to change the value from 5 to 4.

How can you do that?

You can't change a 5 to a 4.

A 5 is an int constant. It has no operation to change it's value. So you need to assign a separate value (other object) to the property that represents 4.

The code will be:

gameObject["amount"] = 4

This is a restriction of immutable objects. You can't change them. Immutable objects are string, int, bool, float and more. Basically the basic object types.

What with mutable objects? Here you can manipulate the object as often as you like without notifying the container it lives in.

Example:

Lets assume you have a property called "last position". The value is a Vector(0,0,0).

gameObject["last position"] = mathutils.Vector([0,0,0])

To get the position object you read it from the property:

lastPosition = gameObject["last position"]

now you can manipulate lastPosition as much as you like:

lastPosition.x = 1.2
lastPosition.y = 2
lastPosition.length = 10.3

You do not need to assign lastPosition back to the property. The object is still the same, but with other content.

This "referring" effects do not just apply to game object properties. This applies to all containers e.g. list, dict, even module. They store a reference to a specific object. You can manipulate the object without reassigning. If you reassign the object, you assign the same reference again.

Be aware the variable refers to the property value. Assigning a different object to the variable will not manipulate the property. The container (game object) does not know about your variables.

Negative Example:

lastPosition = gameObject["last position"]
lastPosition = mathutils.Vector([1.2, 2, 0])

The first line:

  • creates a variable called lastPosition and assigns the property value.

The second line:

  • creates a variable called lastPosition and assigns a new vector object.
  • The variable lastPosition of the first line is gone and will be freed by the garbage collector.
  • The property value still exist, but variable lastPosition does not refer to it. It refers to a different vector object (the one from last line).
$\endgroup$
  • $\begingroup$ ... shorten a GameObject property into a variable? Because it is a 'shortening', an 'abreviation' to always write 'prop' instead of something like 'scene.objects['obj']['prop']'. Sorry if I wasn't clear, I'm not a native english speaker, I'm learning for now. :P And thanks for the answer, that's really helpful! $\endgroup$ – Joel Gomes da Silva Dec 6 '16 at 18:47
  • $\begingroup$ I'm no native speaker too. "Shortening" is no term used within programming as far as I know. I guess you meant to create an alias (not supported by Python), macro (not supported by Python) or caching an operation result in a variable, encapsulate the operation into a function for better abstraction. $\endgroup$ – Monster Dec 7 '16 at 5:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.