2
$\begingroup$

So I'm making an RTS type game, just for practice and exercise, but when I send someone somewhere, I want them to know when they need to stop. I decided this could be done by having the marker that they go to send them a message when they're near it. How can I make the message send only to the guys that are within, say, 3BU from it?

$\endgroup$
3
$\begingroup$

You need logic set up like in the image below on each of your markers.
logic bricks

It is just an Always sensor, set to True level triggering; and a Near sensor. Those two are plugged in to the python controller, which will activate the message actuator. The property in the Near sensor is not needed, that is only to limit what objects get the message.

The script will send a message to every object that is near (3 units or closer) the marker.

import bge

cont = bge.logic.getCurrentController()

list = cont.sensors['Near'].hitObjectList

if cont.sensors['Near'].triggered:
    message = cont.actuators['Message']
    for obj in list:
        message.propName = obj.name
        cont.activate(message)
  • The script gets all the objects that are near the marker and stores it as the list variable (line 5).
  • The if statement works like this, when anything is near the marker, the near sensor is triggered, thus it is True.
    It then loops through the list of objects that are near, and sets the message actuator's "To:" field to one of the objects. (message.propName = obj.name)
  • The last line still part of the loop, activates the actuator - sends the message.
$\endgroup$
  • $\begingroup$ with two monkeys, your system doesn't work. one of them stops moving but the other keeps spinning around the marker. $\endgroup$ – Scalia Sep 11 '15 at 19:55
0
$\begingroup$

I do not recommend to use the "To:" parameter at all. It creates a direct dependency to a single object.

One of the biggest advantages of messages is that you do not get such a dependency. Beside of that you couple the actuator to a single object which is contradictory to your requirement to interact with multiple objects.

Suggestion

I suggest to use a different architecture.

  1. Identify the objects within range
  2. Set according properties of the identified objects.
  3. Objects with that property sense if the property value changed

1) Can be done with a near sensor. It serves several purposes. You set up the detection range, you set up the property name (A) and it senses the objects within that range.

2) Can be done with a Python controller. Due to its dynamic nature there are no sufficient build-in logic bricks. Python controllers do not have additional configuration parameters. So we can use a little trick to setup the value we want to send without hard-coding it. We use a connected message actuator and setup the value of the subject field (B) [The actuator will not be activated]. This looks pretty similar to your proposed idea.

enter image description here

The code retrieves the found objects and sets the property value for each of them:

notifier.py

import bge 

def subjectToNotification():
    hitObjects = getHitObjects()
    if not hitObjects:
        return

    property = getPropertyName()
    value = getPropertyValue()

    for hitObject in hitObjects:
        hitObject[property] = value

While this describes the basic operation we want to achieve, it misses some details. You can use your own flexible implementations of the details. Just in case you have no plan, here is a simple implementation to be appended to notifier.py:

def getHitObjects():
    sensors = bge.logic.getCurrentController().sensors
    sensor = sensors[0]
    return sensor.hitObjectList

def getPropertyName(): # (A) and (C)
    sensors = bge.logic.getCurrentController().sensors
    sensor = sensors[0]
    return sensor.propName

def getPropertyValue(): # (B)
    actuators = bge.logic.getCurrentController().actuators
    actuator = actuators[0]
    return actuator.subject

3) The sensed objects need to check if they are sensed. As we know the property value gets set, we can use a property sensor to check the property (C). Example: enter image description here

Be aware this will not detect subsequent notifications of the same value. If you need it that way you should explicitly reset the property after it changed. enter image description here

I hope it helps

PS: With the above implementation (A) and (C) should have the same property name.

$\endgroup$

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.