BGE Logic Nodes -  V. 0.0.8

 

We have a Door object with an action that opens it, when played from frame 50 to frame 100, and closes it, when played from frame 100 to 50.

The Door is the Owner GameObject.

 

Let's look at this setup:

 

 

Figure 1

 

Condition:

 

MousePressed, Pulse OFF, Left Button.

 

The output of this condition is FALSE, if the left button of the mouse is not pressed.

It is TRUE when:

1. the left button is pressed

2. the left button was not pressed in the last evaluation cycle

So a Mouse Pressed condition, when Pulse is OFF, acts like a a Value Change detector: when the mouse button state passes from “raised” to “lowered”, the condition is TRUE. All other times, the condition is FALSE.

 

In other words, when Pulse is OFF, this is valid, but redundant:

 

 

Figure 2

 

The setup in Figure 1 makes the door play the open animation every time the user presses the left button.

A more precise door wouldn't open if it is alreay open. To do that, we need to keep track of the status of our door: is it opened or is it closed?  We can setup an object o have a property with an certain initial value like this:

 

 

Figure 3

 

In this case I used another “Owner GameObject” parameter for sake of clarity but all Owner GameObject in a tree are the same object. In other words, Figure 3 is equivalent to:

 

 

Figure 4

 

 

The Always condition, when Repeat is OFF, it's actually a “One Time Only” condition. It is TRUE just the first time, then it will be always FALSE. When Repeat is ON, it becomes a “Every Time” condition: it is always TRUE. I gladly accept name suggestions to replace that “Always”.

 

We can skip that initial setup of the property STATUS if we already know a valid default value for the property. We know that our door can be either OPENED or CLOSED and we can also say that all doors starts as CLOSED.

Considering that, instead of setting the property we take it for defined or having a default value if not defined yet, with a Get Game Object Property parameter.

Let's remember – especially to myself here – that we are trying to open the door, when the left mouse button is pressed, only if it is closed: right know it opens every time the mouse is pressed.

 

 

Figure 5

 

The Get Game Object Property parameter takes a Game Object, checks if the object has a certain property and returns the value of that property or a default value, chosen by the user, if that property does not exist or it has the None value.

The next step is to say: when the mouse is pressed and the door status property is CLOSED, then play the open action. Otherwise, don't.

This is a way to do it:

 

Figure 6

 

If we launch the game there are no apparent changes: the door still opens and, when the animation is finished, if we press the left button again, it opens again.

The difference is that if we set the default string value of the Get Game Object Property parameter from CLOSED to OPENED, the door doesn't open. So the value of our DOOR STATUS property is effectively considered as part of the condition to trigger the open animation.

 

The door re-opens simply because we didn't add the nodes that set the value of DOOR STATUS to OPENED when our open animation finishes playing.

That's precisely what we're going to do now: when the open animation finished playing, the value of the property DOOR STATUS should be set to OPENED.

There's not (yet) a straight way to get the “finished playing” condition but we can do that by monitoring the action status. Like this:

 

 

 

Figure 7

 

 

Let's see what we got.

The Action Status parameter monitors the status of an action layer. For as long as an action is playing in that layer, the parameter returns TRUE, on its Is Playing output, FALSE on its Not Playing output, the name of the action and the frame currently played. When the action stops playing – because it has been stopped or because it has reached its end frame – the Action Status parameter returns FALSE, FALSE, None, 0.0. The fact that if an action is not currently playing there is no actual frame value to get is why, if we want to do something at the end of the animation, we need to check if the frame is near the end frame AND if the action is playing.

The Logic Operation condition takes two values and returns the result of a logical comparison. In our case, we test if the frame of the action is greater or equal to 99. I chose greater or equal to 99 and not equal to 100 because I'm not sure if the last frame is skipped or not. In theory equal to 100 should be fine.

 

Running this new configuration results in a door opening only once, no matter how many times we press the left mouse button. As a reminder, that's because our open action is played only if the value of DOOR STATUS is CLOSED and we set that same value to OPENED when the open action ends.

 

Now we need the reverse operation: close the door when the left mouse button is pressed and the status of the door is OPENED.

Trying to make a bit of free space in the mess, we can do something like this:

 

This is the same we did for the CLOSED value with the open action, the only difference is the condition now checks (for the mouse pressed and) if the value of DOOR STATUS is OPENED. And the action is the close one, of course.

 

If we run the game now, we'll see that the door opens, then if we press the left mouse button it closes. If we press the left button again, the door re-closes. Why? Because we have to re-set the state of the door to CLOSED, when the close animation has finished playing. Otherwise it remains OPENED and the close action can play again and again. So we do it.

 

 

Figure 9

 

And this is the door that opens and closes when it can do so and the user clicks the mouse.