Mastering Reactive Programming in Unity with UniRx
Photo by Mohammad Rahmani on Unsplash
Mastering Reactive Programming in Unity with UniRx
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.
- Defining ReactiveProperty: A ReactiveProperty is created and initialized with a value.
- Registering Subscribers: Subscribers are registered to detect changes in the value of the ReactiveProperty.
- State Change: The value of the ReactiveProperty changes.
- 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.
- Defining ReactiveCommand: A ReactiveCommand is created.
- Defining Execution Conditions: Conditions under which the command will execute are set.
- Registering Subscribers: Subscribers are registered to handle the results of the command execution.
- Executing Commands: The command is executed when specific conditions are met.
- 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