Action sequences with logic bricks - the power of the ActuatorSensor

Hello Blenderheads,

Today I will present you an elegant way to create sequences of actions with logic bricks without the need to define Action parameters twice.

I think a lot of BGE users stumbled across this problem:

How to detect when an action ends?

There are a few solutions, from measuring the time, to counting a property over to check the frame property. The common problem of this solutions is … you need to define the end of the action twice:

A) in the actuator
B) in the measure

This is not really satisfying, especially if you update the end frame at a later stage.

Why is it important to detect the end of an action?
In a lot of cases the action is part of a larger sequence. E.g. walkcycle -> grab door knob -> open door -> release door knob -> walkcycle.

The behavior requires to detect when a part of the sequence ends so it can continue with the next part.

Walkcycle ends on external signal: it ends when the character reached the target position (different topic).
Grab door knob depends on the action: it ends when the action ends.

Our goal is to get an activation signal to OtherActuators when the ActionActuator ends playing.

The obvious solution is: ask the ActionActuator. It knows of the playing state.
To do this you can use the ActuatorSensor.

The ActuatorSensor
The ActuatorSensor sounds a bit strange at the first sight. But it makes perfect sense if you look what it is supposed to do:

  • The ActuatorSensor evaluates positive if the referred actuator is activated.
  • The ActuatorSensor evaluate not positive if the referred actuator is deactivated.
  • Like all sensors - the ActuatorSensor triggers the connected controllers when the evaluation status changes.

It does not matter if the actuator gets deactivated by controller signal or if it deactivated automatically (see: Actuators - A Word on execution). The ActuatorSensor will evaluate the activation state of the referred actuator.

Lets have a look at the timing:

  • Initial the ActionActuator is inactive. Therefore the ActuatorSensor will evaluate to not positive. Lets assume the ActionActuator gets activated within the first frame (t). This means it is playing within the next frame (t+1).
  • The ActuatorSensor senses the ActionActuator is active -> status change to positive.
  • The ActionActuator will end its playing (play mode only!) later (frame t+n) and deactivate itself.
  • The Actuator sensor senses the deactivation and evaluates to not positive.

This is the basic interaction between the ActionActuator and the ActuatorSensor. This example assumes you use an ActionActuator in play mode (the Loop modes do not deactivate automatically).

Right as it is you can use this output to trigger logic to start right after the playing started.

If you want to activate OtherActuators after playing you get two problems:

The ActuatorSensor evaluates “not positive”
To activate an actuator it must receive an activation signal from a connected controller. The (basic) controllers send activation signals when they
A) get triggered by any connected sensor
B) calculate positive sensor evaluation dependent on the controller logic (e.g. AND = all sensor must be positive, OR = any sensor must be positive)

  1. We can use an according controller such as NAND, NOR or
  2. we invert the sensor output by enabling the [INV] button at the sensor.

We decide to use the inverted sensor as this will help us later. We get this sensor evaluation status:


When the AcutatorSensor evaluates positive it returns not positive and vice versa.

The controller activates before playing starts
This is the biggest problem. The ActionActuator does not play initially. The sensor will evaluate this event and activates the OtherActuators via the connected controller. This is something we really do not want.

To solve this we suppress the early activation with an AND controller. We need another sensor that evaluates not positive as long as the ActionActuator didn’t activate. Assuming the ActionActuator starts immediately (e.g. via AlwaysSensor) the DelaySensor delaying 1 frame is a good choice:

  • Initial the Action Actuator is inactive. The ActuatorSensor will evaluate to not positive. As it is inverted it evaluates positive.

  • The DelaySensor is still in delay and evaluates not positive.

  • The AND controller triggers but sends a deactivation signal.

  • The ActuatorSensor senses the ActionActuator is active -> status change to positive. It is inverted = status change to not positive.

  • The DelaySensor times out and evaluates positive.

  • The AND controller triggers but sends a deactivation signal.

  • The ActionActuator will end its playing (play mode only!) (frame t+n) and deactivate itself.

  • Nothing happens to the sensors.

  • Nothing happens at the AND controller.

  • The ActuatorSensor senses the deactivation and evaluates to not positive. As it is inverted it evaluates positive.

  • The DelaySensor is remains in positive.

  • The AND controller combines the sensor signals to an activation signal to all connected actuators.

Hint: This behavior works pretty well together with states. But you need at least two DelaySensors as they do not restart it’s when they remain active (connected to a controller) between state changes [see the demo in the next post].

I think this is enough theory. In the next post I will show you how to set up the logic bricks…

When working with sequences I prefer to use states. This allows to deal with the logic brick “noddles” in a much cleaner and more organized way. (If you run out of states - it is time to switch to Python ;)).

This example does a sequence of two actions:

  • move
  • trun

The actions play what the name says the move (forward) and turn (right). I enabled [Add] to get a nice motion.
This is the setup for

state “Turn”:



You see the ActionActuator playing 5 frames (it will take more than 5 frames to play it because of the frame rate).
There is the ActuatorSensor with inverted output and the DelaySensor with a one frame delay.
They trigger an AND controller which activates a StateActuator to

state “Move”:



You see the ActionActuator playing 11 frames to show it can have a different length.
There is the ActuatorSensor with inverted output and (a different) DelaySensor with a one frame delay.
They trigger an AND controller which activates a StateActuator back to state “Turn”

As exercise you can go and add one or more actions and states to the demo file.

I hope it helps
Monster

PS: The Python script prints the state evaluation of the sensors to the console. It is not necessary to run the logic bricks.

Attachments

ActuatorSensor.demo.blend (453 KB)