1
$\begingroup$

I'm looking for a way to have object 1 assign a random value to property "Gold". If the property value turns out to be higher than 10, I have a Property Sensor to check for that, and if it's true, it will activate a Message Actuator with the subject "Add Gold" and the property "Gold" as the body type (Not text).

In my head, this will embed the property "Gold" into the message "Add Gold" that is being send out to other objects.

Now, in object 2, I have a Message Sensor that looks for a message called "Add Gold". This is then connected to a Property Actuator which will add the message to the property "Total Gold".

The problem here is that this does not seem to work, and I'm not sure what I'm doing wrong.

Object 1 logic that will embed the value "Gold" to a message and send it to Object 2. Object 1

Object 2 logic that will look for added gold message, and add the value in the message body to it's property "Total Gold". Object 2

I have the information sent to a Game Controller (Empty object) which handles all important global information so far. On my HUD screen, I have a counter working as a total resources counter, which includes among others, the gold values I want to send. The HUD counter then copies the property value "Total Gold" from the game controller, but nothing appear on the HUD (The counter starts, and stays at a -1 value, even after picking up the resource boxes (the grey ones being dropped by the yellow cubes) enter image description here

$\endgroup$
2
  • $\begingroup$ Have you tried set a value to add in the property actuator? $\endgroup$ Commented Jul 31, 2017 at 17:03
  • $\begingroup$ Set an initial value? I believe I set it as an integrer in the game controller object, and default to 0. The counter itself doesn't have an initial value since it copies the value from the game controller each game tick. $\endgroup$
    – FreemoX
    Commented Jul 31, 2017 at 17:41

2 Answers 2

4
$\begingroup$

I have done a simple test and it did not work without a value to add to the property. You need to have your logic like this:

enter image description here
The script only activates the actuator "Message", which send the message.

logic.getCurrentController().activate(logic.getCurrentController().actuators['Message'])

And if you dont set a value e.g "15" to add on the property actuator it will not work. You can't do ( + 0 = ?).

enter image description here

EDIT

I failed to make the random actuator work, but it's very easy with python.

For the mineral object: (You may already done this!). 1. Make a proterty call mineral 2. Add a collision sensor(True level triggering) with property player < and > edit object actuator - end object.

enter image description here

For the player object:

  1. Make a proterty call player
  2. Add an always sensor an a python controller
  3. Add a collision sensor(True level triggering) with property mineral to the python controller

enter image description here

Script:

#import needed libraries
from bge import logic
import random

#main function or module.
def main(controller):
    # Param controller = bge.logic.getCurrentController
    #eval if collision sensor activated
    if controller.sensors['Collision'].positive:

        # Gold attr = gold attr  + Random num
        controller.owner['gold'] += random.randint(10, 50)
    print(controller.owner['gold'])


#Game update######################## every frame if always sensor true level triggering

#call function        
main(logic.getCurrentController())

EDIT

to send the message use:

controller.owner.sendMessage('subject', body = str(controller.owner['gold']), to = 'object' )

and retrive it:

if logic.getCurrentController().sensors["Message"].positive:
    gold = logic.getCurrentController().sensors["Message"].bodies[0]

Api sendMessage

Api messageSensor.bodies

$\endgroup$
10
  • $\begingroup$ Yes, this is the standard (?) way of doing it, at least how I've done it before. But the problem is that the property value "Gold" is a randomly generated value upon the creation of the resource cube, so it's not a set value. Sometimes the player will pick up 30 gold from one cube, another they'll pick up 13 gold, and another 47 gold, etc. Judging from your response, I assume this is not possible without scripts? And I don't know Python, but doesn't your script simply activate the 'Message' actuator upon receiving a signal? $\endgroup$
    – FreemoX
    Commented Jul 31, 2017 at 20:56
  • $\begingroup$ Also, to add to my comment. What is your personal opinion? Should I let the resource cubes generate a random value, and send it to the game controller and resource counter, or should I add a resource controller object that handles the randomness and counting of the resources upon receiving a message from the resource cubes upon being picked up? $\endgroup$
    – FreemoX
    Commented Jul 31, 2017 at 20:57
  • 1
    $\begingroup$ Ok i dont understood the question the first time. And i test it in game that am making that why i use a script that you may not need. I will edit the answer but in cople of minutes. About my opinion a let you know in the answer :). $\endgroup$ Commented Jul 31, 2017 at 21:18
  • $\begingroup$ Hmm... This is interesting. It applies a random number as I want it to, and I could modify this to work with a setup. But is this not the same as using the random actuator? It calls a random number and applies it to a selected property, just like this script does. But is it possible to modify this script to send the "gold" value to another object? Without copying it, as it will require a work-around to add the values instead of setting them. Could you do "print(controller.GameController['Gold'])" to send the values to the game controller object? Sorry for all the questions. $\endgroup$
    – FreemoX
    Commented Jul 31, 2017 at 22:23
  • 1
    $\begingroup$ Glad to help. Just make sure you add a Message sensor named "Message" on the object who retrive the message or the line 'logic.getCurrentController().sensors["Message"].bodies[0]' will not work. $\endgroup$ Commented Jul 31, 2017 at 23:08
1
$\begingroup$

Due to it's dynamically behavior you will need a Python controller to deal with the message bodies (yes there can be more than one).

Your requirement:

add the value in the message body to it's property "Total Gold"

I assume following:

  • You have a single message sensor that senses for messages with gold value in body (subject Add Gold)
  • You have a single property actuator that adds the value to the "Total Gold" property

You connect these two logic bricks via a Python controller that runs following code:

sumBodiesToValue

import bge

controller = bge.logic.getCurrentController()
messageSensor = controller.sensors[0] 

if (messageSensor.positive):
    receivedGoldValue = sum( int(body) for body in messageSensor.bodies)

    propertyActuator = controller.actuators[0]
    propertyActuator.value = str(receivedGoldValue)
    controller.activate(propertyActuator)

enter image description here

How it works:

  • When the sensor receives at least one message (there can be multiple messages from different senders, one or none message at the same time) the Python controller gets triggered

  • The triggered Python controller runs the above code and

    • checks the sensor for detecting a message (sensor.positive)

    • reads all bodies and sums them up

    • places the result in the value field of the property actuator

    • activates the property sensor to let it perfom it's magic (adding to property)

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .