In the past I’ve written about how we use reactive programming in Wunderlist. Reactive programming leverages IObservable and IObserver to create and subscribe to streams of data in your app. Not only typical data like lists and tasks can be streamed but also things like timers, keyboard, controller and mouse inputs. Unity3D has its own Rx implementation called UniRx and here is an example of what you can do with it.
RxTest
app
app
selected, click Add Component in the inspector.App
using UnityEngine;
using UnityEngine.UI;
public class App : MonoBehaviour
{
public Text TextBlock;
}
app
Text
to the App (script) Text Block
placeholderIn the next code, a ReactiveProperty of type int is added for the counter.
The reactive property has a method to register to changes to update a UI.Text. In our example, we overload SubscribeToText
with a Func that transforms an int into a string with some formatting.
using UniRx;
using UnityEngine;
using UnityEngine.UI;
public class App : MonoBehaviour
{
public Text TextBlock;
private ReactiveProperty<int> _counter = new ReactiveProperty<int>();
private void Start()
{
_counter.SubscribeToText(TextBlock, i => $"Shots fired: {i}");
}
}
Finally it is time to create an Observable that creates a stream of clicks. UniRx has a function UpdateAsObservable
that transforms the Update event to an observable. We start by filtering this stream by checking if the mouse button is down. By this time, we throttle the events to emit every 500 milliseconds and finally subscribe to the observable by calling OnClick
.
Notice how the value of Reactive Property _counter
in the OnClick
method is incremented and the UI.Text automatically updates.
using System;
using UniRx;
using UniRx.Triggers;
using UnityEngine;
using UnityEngine.UI;
public class App : MonoBehaviour
{
public Text TextBlock;
private ReactiveProperty<int> _counter = new ReactiveProperty<int>();
private void Start()
{
this.UpdateAsObservable()
.Where(_ => Input.GetMouseButton(0))
.ThrottleFirst(TimeSpan.FromMilliseconds(500))
.Subscribe(OnClick);
_counter.SubscribeToText(TextBlock, i => $"Shots fired: {i}");
}
private void OnClick(Unit x)
{
_counter.Value++;
}
}