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!