Just a little bit about UniRx for Unity

public void Init(Player player)
{
  _player = player;
  _player.HealthChanged += SetHealth;
  _player.ManaChanged += SetMana;
}

public void Dispose()
{
  _player.HealthChanged += SetHealth;
  _player.ManaChanged += SetMana;
}

And the Player itself will look something like this

public class Player : IPlayer
{
  private int _health;
  private int _mana;

  public int Health => _health;
  public int Mana => _mana;

  public event Action<int> HealthChanged;
  public event Action<int> ManaChanged;
}

And if we want to add an interface for the player, then we will come to this option

public interface IPlayer
{
  public int Health { get; }
  public int Mana { get; }

  public event Action<int> HealthChanged;
  public event Action<int> ManaChanged;
}

What is the problem? The fact is that with the growth of data for display, it will be necessary to go down to the Dispose method each time and do not forget to unsubscribe, as well as create a method for each value. After all, I can’t even create n identical views to show values

ReactiveProperty

How will the reactive field help in this case? It allows you to subscribe and unsubscribe in the same place, although you still have to use the disposition.

private List<IDisposable> _disposables = new List<IDisposable>();

public void Init(Player player)
{
  player.Health
    //создаем подписку
    .Subscribe(v => { _healthView.text = v.ToString(); })
    //добавляем подпику в список очищаемых обьектов
    .AddTo(_disposables);
  player.Mana.Subscribe(v => { _manaView.text = v.ToString(); }).AddTo(_disposables);
}
        
public void Dispose()
{
  foreach (var disposable in _disposables)
  {
    disposable.Dispose();
  }
  _disposables.Clear();
}

What’s the charm? The fact that the Subscribe method, with which we subscribe to the stream, returns IDisposable, which means that we can immediately add this to the list, which will then be cleared. At the same time, you can not be afraid of subscriptions using lambdas.

Now you can look at the Player

public class Player : IPlayer
{
  private ReactiveProperty<int> _health = new();
  private ReactiveProperty<int> _mana = new();
        
  public IReadOnlyReactiveProperty<int> Health => _health;
  public IReadOnlyReactiveProperty<int> Mana => _mana;
}

Since ReactiveProperty implements the IReadOnlyReactiveProperty interface, we can leave it sticking out without fear of unsolicited changes.

ReactiveCollection/ReactiveDictionary

The same as reactive fields, but here you need to separately subscribe to each event associated with the collection.

public void Init(IReadOnlyReactiveCollection<Player> players)
{
  players
    //говорим, что хотим отслеживать
    .ObserveAdd()
    //подписываемся
    .Subscribe(v => 
    {
      //работаем с добавленным элементом
      Debug.Log(v.Value);
    }).AddTo(_disposables);
  players.ObserveRemove().Subscribe(v => { Debug.Log(v.Value); }).AddTo(_disposables);
  players.ObserveReplace().Subscribe(v =>
  {
    Debug.Log(v.OldValue);
    Debug.Log(v.NewValue);
  }).AddTo(_disposables);
}

But what about “everything is a flow”?

UniRx allows you to stream a lot of things: input, unit update cycle, components. And also skip changes, make delays and many other things (many of which I don’t even know about). But I wanted to show the beauty of everyday use, not increase the cognitive load. I think those who want to go deeper can follow the links attached to the tutorials or go read the documentation.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *