hi everyone
i’m building a game usind only the logic bricks of UPBGE and some expression actuator to reduce numbers of bricks in layers.
___ it looks like when i put more expression controller in a game, for some unknown reasons they don’t works anymore, i tried different way to write the expression:
sensor (continue message named life=0) AND actuator → expression (frame=1070) → actuator (action)
i also tried to write ‘frame=1070‘ but the BGE/UPBGE ignores the frame number and waits for the end of the action (sensor)
if i write frame=1070 he ignores the message sensor.
the only solution i found that works was to change the message sensor name to life_0 and write in the expression box:
frame = 1070 AND life_0 = True
but why it doesn’t work if i don’t add the sensor in the expression?
could someone tell me in which cases expression doesn’t works (talking more about combination of bricks linked to them and also using property not linked)
and in other cases when i link an actuator sensor to an expression controller with a long line like: frame=5 OR frame=8 OR … it doesn’t send any trigger
i use this to chose when take out life because i can’t do it so easly with the property sensor.
Brick works as it should, the actual problem is logical. Positive sensors won’t fire an expression controller unless the condition you’ve written down evaluates to true; and this condition is only ever checked when at least one sensor is positive.
frame = 1070 -> fires only if frame equals 1070. Sensors connected to the controller will not make the controller run unless frame equals 1070.
frame = 1070 AND life_0 = True -> fires only if frame equals 1070 and life_0 is positive. L_STOMP will not make the controller run; if L_STOMP is positive, the expression will be checked and the controller will run only if it evaluates to true.
Fix: Parentheses do the mathematical funk.
(life_0 = True OR L_STOMP = True) AND frame = 1070 -> fires if either sensor is positive and frame equals 1070.
(life_0 = True AND L_STOMP = True) AND frame = 1070 -> fires if both sensors are positive and frame equals 1070.
(life_0 = True OR L_STOMP = True) OR frame = 1070 -> fires if (either sensors are positive) or frame equals 1070.
(life_0 = True AND L_STOMP = True) OR frame = 1070 -> fires if (both sensors are positive) or frame equals 1070.
thanks for your help, this means i will always have to call that message sensor…
but how to solve the last part, about a long line of property value with OR?
it doesn’t works if there are many value to verify
(CONDITION) AND (prop0 = value OR prop1 = another_value OR prop2 = yet_another_value)
You can chain it like so, length doesn’t matter. You have to write it properly.
frame = 5 --> condition.
frame = 5 OR frame = 8 --> condition1 OR condition2
life_0 = true --> condition.
life_0 = True AND L_STOMP = True --> condition1 AND condition2
(frame = 5 OR frame = 8 ) OR (life_0 = True AND L_STOMP = True) --> (condition1) OR (condition2) --> (everything within these parentheses counts as a single condition) OR (everything within these parentheses counts as a single condition)
if you cannot grasp this concept, I cannot help you.
i understand the sense of parentheses, it’s like math
so the result for example may be?: L_STOMP = True AND (frame = 1 OR frame = 5 OR frame = 10 OR frame = 15 OR frame = 20)
i can use only 127 letters in that expression box
i created a very simple project to reproduce this expression but if i link a message sensor to this controller it doesn’t work even if the pulse is always positive and i write: message = True AND (…
Message sensor on positive pulse will still output negative if no message is received or the sensor isn’t listening for the right subject. It’s not that the controller or the expression stop working when you use a certain sensor, it’s that the sensor in question is not getting triggered.
Aye, bricks have their limits- that’s why we use Python.
what is the script i can easly use to send an active pulse to a controller when the own property (frame) have each values i need? if it is simple otherwise i will continue it using more logic bricks, i tried few times to learn it but it becomes confusing when you don’t have a slow and approfondite manual with example of python!!
from bge import logic
cont = logic.getCurrentController() #get controller running this text data block
own = cont.owner #object that is running this controller
if own["frame"] in [5, 8, 3, 7]:
#check that prop "frame" matches any number in list
#then go through each actuator connected to controller and activate them
for actuator in cont.actuators:
cont.activate(actuator)
It’ll take some more python.
Expanding on the code we have so far, we could do
from bge import logic
cont = logic.getCurrentController()
own = cont.owner
#we'll create a property to store values already activated
#this piece will only run if we haven't yet created the property
if "actValues" not in own:
own["actValues"] = { "unused":[5, 8, 3, 7], "used":[] }
#own["actValues"]["unused"] = values that haven't triggered controller
#own["actValues"]["used"] = values that already triggered controller
if own["frame"] in own["actValues"]["unused"]:
#check that frame equals an unused value before firing the controller
#then remove it from "unused" so this value doesn't activate again
own["actValues"]["unused"].remove(own["frame"])
#now we add frame to "used", in case we want to restore it.
own["actValues"]["used"].append(own["frame"])
#triggering different outcomes depending on the value of frame
if own["frame"] == 5: actuator_name = "Actuator_1"
else: actuator_name = "Actuator_2"
cont.activate( cont.actuators[actuator_name] )
Just for the sake of a clear example, we simply switch which actuator we want the controller to fire depending on whether the value of frame is 5. For a more sophisticated thingy, details be needed.
i appreciate a lot your help, but the code only run the first actuator with infinite pulses when “frame” reachs 5
had i only to change the name of “Actuator_1” and “Actuator_2” ? because if i don’t do it no pulse will be fair
“Actuator_1” and “Actuator_2” would be the names of actuators connected to your controller.
The name is stored in a variable, the variable is used to locate the actuator within a list.
If actuator_name is set to “SS_C10” then cont.actuators[actuator_name] is equal to the actuator SS_C10, if an actuator of that name is conected to the controller running the code.
Scripts are executed by python controllers. They are controllers and need to be triggered by at least one sensor to execute. They do not trigger other controllers.
Btw. this belongs to all type of controllers.
To trigger a controller you need to setup a sufficient configuration on the sensors. In your case you could have a property sensor that checks if property frame equals 1070.
Alternative you use a property sensor that checks if property “frame” changed and you check the value within your controller.