I am working on a simple hint dialogue where the player would click on an object, which would send a message with a common subject, but an object-specific body text, to the hint text. This makes it so I don’t need more than one text object. Here is the code:
import bge
cont = bge.logic.getCurrentController()
pC = cont.actuators["propChange"]
mess = cont.sensors["mess"]
#Properties
pink = "The box looks like it is pink"
blue = "The text is an overlay"
yellow = "Animations are optional"
red = "The box appears to be red"
green = "The text is customizable"
def main():
if mess.positive:
typeSent = mess.bodies[0]
if typeSent=="red":
pC.value = red
cont.activate(pC)
if typeSent=="green":
pC.value = green
cont.activate(pC)
if typeSent=="yellow":
pC.value = yellow
cont.activate(pC)
if typeSent=="blue":
pC.value = blue
cont.activate(pC)
if typeSent=="pink":
pC.value = pink
cont.activate(pC)
else:
pass
The message interprets okay, but when it activates the string I get this on my text object:
[[The not found…]]
It’s saying that it can’t find the variable that I’m pointing to. I’m not using a variable, it is a text string. What am I doing wrong?
UPDATE: It’s not Python, it’s blender. Using print(pink) works fine. It also works when I put a number instead of text. What is the deal here?
It matches each of my statements, that I’m sure of. The text object will change to the correct string, but the script will not read the string correctly.
The Property Actuator interprets the value field. This way you can use property names and operators too (e.g. “a + b + 3”).
To tell the interpreter you mean a string constant you need to surround the string with “”.
Example:
anyway if you had write all code should not work correctly
if is a script mode lack “main()” at the end.
in this caser should make nothing
if is module mode (i suppose) it should work correctly only one time.
with module mode the code should be written in this way:
import bge
#Properties
pink = "The box looks like it is pink"
blue = "The text is an overlay"
yellow = "Animations are optional"
red = "The box appears to be red"
green = "The text is customizable"
def main(cont): #<- the "hook updated"
pC = cont.actuators["propChange"]
mess = cont.sensors["mess"]
if mess.positive:
typeSent = mess.bodies[0]
if typeSent=="red":
pC.value = red
cont.activate(pC)
if typeSent=="green":
pC.value = green
cont.activate(pC)
if typeSent=="yellow":
pC.value = yellow
cont.activate(pC)
if typeSent=="blue":
pC.value = blue
cont.activate(pC)
if typeSent=="pink":
pC.value = pink
cont.activate(pC)
else:
pass
with script mode in this way:
import bge
cont = bge.logic.getCurrentController()
pC = cont.actuators["propChange"]
mess = cont.sensors["mess"]
#Properties
pink = "The box looks like it is pink"
blue = "The text is an overlay"
yellow = "Animations are optional"
red = "The box appears to be red"
green = "The text is customizable"
def main():
if mess.positive:
typeSent = mess.bodies[0]
if typeSent=="red":
pC.value = red
cont.activate(pC)
if typeSent=="green":
pC.value = green
cont.activate(pC)
if typeSent=="yellow":
pC.value = yellow
cont.activate(pC)
if typeSent=="blue":
pC.value = blue
cont.activate(pC)
if typeSent=="pink":
pC.value = pink
cont.activate(pC)
else:
pass
main() #<<< need explicit call
import bge
DATA = {
"pink": "The box looks like it is pink",
"blue": "The text is an overlay",
"yellow": "Animations are optional",
"red": "The box appears to be red",
"green": "The text is customizable",
}
def main(cont):
mess = cont.sensors["mess"]
if mess.positive:
typeSent = mess.bodies[0]
if typeSent in DATA:
pC = cont.actuators["propChange"]
pC.value = DATA[typeSent]
cont.activate(pC)
Thanks, I’ve always used a dictionary call before, rather than a class property.
A little Off topic, I’ve often wondered why BGE swapped from using class type properties to using dictionary type ones… it used to be own.health but became own[‘health’].
In my own projects I’ve noticed a few times when the second one would be better, but I just wondered.
I never saw an explanation of this decision. And yes it felt really strange at the beginning. But if you look at this it was a natural decision as it prevented the usage of property style attributes (KX_GameObject.worldPosition vs. KX_GameObject.getWorldPosition()).
Additional benefits of dictionary style access:
property names can contain spaces, numbers special characters
no naming conflicts (e.g. .state vs [“state”])
dynamic property name processing (e.g. “myprop” + str(index))
getting a list of all current property names
The attribute KX_FontObject.text is a natural part of this object (it already existed in the Blender world). The additional “Text” BGE property was introduced to support the GUI (logic bricks) which is based on BGE properties.