ReactiveX and Unity3D: part 2b

I wanted to add a little bonus material to the previous part in this practical series on ReactiveX in Unity. We added a feature where we could run by holding the Shift key. Some games instead give you the option of toggling run by pressing Shift. With our Observables controller, that change is super easy.

One of the nicer things about a signals-based architecture is we can change how the signal is produced without altering the code that reacts to the signal. We originally defined the run signal like this:

Run = this.UpdateAsObservable()
  .Select(_ => Input.GetButton("Fire3"))
  .ToReadOnlyReactiveProperty();

Every Update, Run updates with a true value if Shift (the "Fire3" input axis) is pressed, and false otherwise. (And just for ease of use in other code, we stored it as a Reactive Property.)

Changing that to a toggle input is as easy as this:

var runValue = false;
Run = this.UpdateAsObservable()
  .Where(_ => Input.GetButtonDown("Fire3"))
  .Do(_ => runValue = !runValue)
  .Select(_ => runValue)
  .ToReadOnlyReactiveProperty();

runValue is state-by-closure; any Update where the Shift button was pressed, we first negate runValue and then select it. The Do method isn't strictly necessary here; we could negate the state and return the new value in the function we pass to Select. However Do makes it explicit that some side-effecting is going on, in this case state manipulation, and as such serves as a warning flag for your fellow programmers (including your future self).

Of course you should be careful that no one interferes with runValue, so you may want to protect it by hiding it off in a utility function somewhere.

The most important thing is that we didn't change any lines of code except those responsible for producing the run signal. All the code that uses it remains unchanged and working as expected!