Multiple Messages into Python Controller

I’ve been trying for at least an hour now to try to figure out the proper syntax but I just can’t get it. I’m not familiar with Python but logic makes sense to me. I’m using Blender 2.57.

I’ve got a series of doors that are supposed to teleport the main actor to the other corresponding door. When I press the appropriate key when next to the door it will send a message to my actor. Each message is just the name of the door it should be going to ie. “door2”.

Here is the non-functional script I have at the moment.

from bge import logic

cont = logic.getCurrentController()
obj = cont.owner
sce = logic.getCurrentScene()
messSensor = cont.sensors["Doors"]
subject = messSensor.getSubject()

if subject == "door2":
    target = sce.objects['door2']
    obj.position = target.worldPosition
    
if subject == "door2start":
    target = sce.objects['door2start']
    obj.position = target.worldPosition

I previously had my message sensor looking for a specific message but that would quickly make a mess of my logic bricks when I started setting up more doors. So I changed the message sensor (“Doors”) to accept all messages.

I feel like I’ve got the “if” statements set up properly. Is it just a mistake in pulling the messages from the sensor?

Thanks for your patience!

What exactly is going wrong? you could try changing your own.position to own.worldPosition.

If you plan on adding more doors I would make things even more dynamic by manually typing in object names. So for your non-working script you could change it too:


from bge import logic
cont = logic.getCurrentController() 
obj = cont.owner 
sce = logic.getCurrentScene() 
messSensor = cont.sensors["Doors"] 
subject = messSensor.getSubject()  

if subject != None:
     target = sce.objects[subject]
     obj.position = target.worldPosition

And on the door you could put a code like this:


if key_press.positive:
   message.subject = own.name
   cont.activate(message)

And then you wouldn’t have to type in the names of your doors every single time.

I wouldn’t even use messages.

I assume you havea near sensor that looks for the player (or whatever to teleport).
The near sensor gives you the objects within range (see API). The opposite door should be known by the door already.

Now you can teleport all these objects (or a subset) to the other location. This means the door is the active part. No need to add this logic to the player.
The benefit is that even enemies could teleport with the door without further change.

As you want the enable teleport on keypress you can combine the nearsensor with a keyboard sensor.

Now to the message sensor:

Message sensors could receive multiple messages in one frame. E.g. if you have multiple doors and all of them sends it’s targets around you get a list of messages. That is the reason you should better use a loop:



sensor = ...
for msgNum in range(len(sensor.subjects)):
   subject = sensor.subjects[msgNum] 
   body = sensor.bodies[msgNum]
   if subject  == "whatever":
      myWhatever(suject, body)

I hope it helps

Thank you both for your help! I got it working now exactly how I wanted and managed to get it working more efficiently too. The code is now:

from bge import logic

cont = logic.getCurrentController()
obj = cont.owner
sce = logic.getCurrentScene()

sensor = cont.sensors['Doors']
for msgNum in range(len(sensor.subjects)):
   subject = sensor.subjects[msgNum] 
   body = sensor.bodies[msgNum]
   target = sce.objects[subject]
   obj.position = target.worldPosition

I’m not sure if I did exactly what either of you said but your snippets provided were a huge help. I don’t need to add a new ‘if’ statement for each door now which will save me lots of time.

Thanks again.