← Back to list

Mastering Reactive Programming in Unity with UniRx

Photo by Mohammad Rahmani on Unsplash

Hwanuk Song · 2024-07-17 05:28 · 23 claps · 2.9 min read
#unity #unirx #reactive-programming #game-development #csharp
Open on Medium ↗
Wiki topics: 💻 · Programming 🌐 · Web Development 🎮 · Gaming 🥊 · Combat Sports

Mastering Reactive Programming in Unity with UniRx

Photo by Mohammad Rahmani on Unsplash

Photo by Mohammad Rahmani on Unsplash

1. Overview of the UniRx Library

UniRx is a reactive extension library for Unity. It applies the ideas of Rx (Reactive Extensions) to Unity, helping game developers manage data streams and event handling more efficiently. This makes asynchronous tasks and event-based programming easier, significantly improving code readability and maintainability.

2. Concepts of UniRx’s ReactiveProperty and ReactiveCommand

ReactiveProperty

ReactiveProperty is a special type provided by UniRx that detects changes in data and reacts to them. It extends Observable, allowing it to detect changes in value in real-time and notify subscribers.

  1. Defining ReactiveProperty: A ReactiveProperty is created and initialized with a value.
  2. Registering Subscribers: Subscribers are registered to detect changes in the value of the ReactiveProperty.
  3. State Change: The value of the ReactiveProperty changes.
  4. Notify Subscribers: When a change is detected, registered subscribers are notified.

ReactiveCommand

ReactiveCommand is a type in UniRx used to manage the execution of commands and their results. It is mainly used for handling user input, such as button clicks, and managing the command’s execution status and results as Observables.

  1. Defining ReactiveCommand: A ReactiveCommand is created.
  2. Defining Execution Conditions: Conditions under which the command will execute are set.
  3. Registering Subscribers: Subscribers are registered to handle the results of the command execution.
  4. Executing Commands: The command is executed when specific conditions are met.
  5. Notify Subscribers: The results of the command execution are sent to the subscribers.

3. Disadvantages of Excessive Use of ReactiveProperty and Advantages of ReactiveCommand

Disadvantages of Excessive Use of ReactiveProperty

  • Memory Leaks: ReactiveProperty detects and reacts to changes in value through the subscribe mechanism. If subscriptions are not explicitly unsubscribed, memory leaks can occur. In Unity, if subscriptions are not explicitly unsubscribed when game objects are destroyed, it can lead to memory leaks.
  • Complex Debugging: Managing state changes with ReactiveProperty can result in multiple ReactiveProperties influencing each other. This makes it challenging to track where state changes occur and requires complex debugging, especially when various states are intertwined.
  • Performance Degradation: ReactiveProperty notifies all subscribers whenever the value changes. Frequent state changes can lead to performance degradation. In large-scale game projects, hundreds of ReactiveProperties can operate simultaneously, leading to significant performance issues.

Advantages of ReactiveCommand

  • Command-Oriented Design: ReactiveCommand is designed in a command-oriented manner to handle specific events. This structure separates logic clearly, making maintenance easier. It is useful for reacting to clear user actions like button clicks.
  • Conditional Execution: ReactiveCommand can be designed to execute only when certain conditions are met. For example, an attack command can be executed only when the player possesses a specific item. This helps optimize performance by preventing unnecessary command executions.
  • Code Readability: The command-oriented nature of ReactiveCommand enhances code readability. Event handling logic is separated by commands, making it easier to understand the roles and behaviors of each command during collaboration.

4. Use Cases and Examples of ReactiveProperty and ReactiveCommand

Example Using Only ReactiveProperty Without ReactiveCommand

using UnityEngine;
using UnityEngine.UI;
using UniRx;

public class ButtonHandler : MonoBehaviour
{
    [SerializeField] private Button button;

    public ReactiveProperty<bool> IsButtonClicked { get; private set; } = new();

    private void Start()
    {
        // Change ReactiveProperty value on button click
        button
            .OnClickAsObservable()
            .Subscribe(delegate { OnClickButton(); })
            .AddTo(this);

        // React to value change
        IsButtonClicked
            .AsObservable()
            .Subscribe(IsButtonClickedHandler)
            .AddTo(this);
    }

    private void OnClickButton()
    {
        IsButtonClicked.Value = true;
    }

    private void IsButtonClickedHandler(bool isButtonClicked)
    {
        if (isButtonClicked)
        {
            Debug.Log("Button Clicked!");
            IsButtonClicked.Value = false; // Reset state
        }
    }
}

Example Combining ReactiveProperty and ReactiveCommand

using UnityEngine;
using UnityEngine.UI;
using UniRx;

public class ButtonHandler : MonoBehaviour
{
    [SerializeField] private Button button;

    public ReactiveCommand OnClickButtonCommand { get; private set; } = new();
    public ReactiveProperty<bool> IsButtonEnabled { get; private set; } = new();

    private void Start()
    {
        // Execute command on button click
        button
            .OnClickAsObservable()
            .Subscribe(delegate { OnClickButton(); })
            .AddTo(this);

        // React to command execution
        OnClickButtonCommand
            .Subscribe(delegate { OnClickButtonExecuted(); })
            .AddTo(this);

        // Interact with ReactiveProperty and button
        IsButtonEnabled
            .AsObservable()
            .Subscribe(IsButtonEnabledHandler)
            .AddTo(this);
    }

    private void OnClickButton()
    {
        OnClickButtonCommand.Execute();
    }

    private void OnClickButtonExecuted()
    {
        Debug.Log("ButtonHandler.OnClickButtonExecuted(): Entered");
        IsButtonEnabled.Value = !IsButtonEnabled.Value; // Toggle state value
    }

    private void IsButtonEnabledHandler(bool isEnabled)
    {
        button.interactable = isEnabled;
    }
}

5. Conclusion

Using UniRx makes reactive programming in Unity much simpler. By appropriately using ReactiveProperty and ReactiveCommand, you can enhance code readability and maintainability while efficiently handling data.


메타데이터
post_id
5e16fd8930cf
slug
mastering-reactive-programming-in-unity-with-unirx-5e16fd8930cf
url
https://medium.com/@olgaphila40/mastering-reactive-programming-in-unity-with-unirx-5e16fd8930cf
canonical_url
https://medium.com/@olgaphila40/mastering-reactive-programming-in-unity-with-unirx-5e16fd8930cf
author_url
https://medium.com/@olgaphila40
status
ok
fetched_at
2026-07-23 09:10:31