{"id":15160301,"url":"https://github.com/neuecc/unirx","last_synced_at":"2025-09-30T11:31:56.453Z","repository":{"id":15213065,"uuid":"17941520","full_name":"neuecc/UniRx","owner":"neuecc","description":"Reactive Extensions for Unity","archived":true,"fork":false,"pushed_at":"2024-02-16T10:42:13.000Z","size":8416,"stargazers_count":6975,"open_issues_count":246,"forks_count":887,"subscribers_count":375,"default_branch":"master","last_synced_at":"2024-05-21T19:27:24.773Z","etag":null,"topics":["c-sharp","linq","reactive-extensions","rx","unirx","unity"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neuecc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2014-03-20T12:23:28.000Z","updated_at":"2024-05-21T12:09:09.000Z","dependencies_parsed_at":"2022-07-14T04:30:36.888Z","dependency_job_id":"d563411c-8d31-44df-a735-e03dc5705009","html_url":"https://github.com/neuecc/UniRx","commit_stats":{"total_commits":949,"total_committers":41,"mean_commits":"23.146341463414632","dds":0.08429926238145413,"last_synced_commit":"6baeccf6c544c155497164327cca72f28163a578"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuecc%2FUniRx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuecc%2FUniRx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuecc%2FUniRx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuecc%2FUniRx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neuecc","download_url":"https://codeload.github.com/neuecc/UniRx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234732482,"owners_count":18878416,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-sharp","linq","reactive-extensions","rx","unirx","unity"],"created_at":"2024-09-26T22:43:42.576Z","updated_at":"2025-09-30T11:31:55.199Z","avatar_url":"https://github.com/neuecc.png","language":"C#","readme":"\u003e [!IMPORTANT]\n\u003e I have started distributing an evolved version of UniRx in [Cysharp/R3](https://github.com/Cysharp/R3), please use it instead of UniRx.\n\nUniRx - Reactive Extensions for Unity\n===\nCreated by Yoshifumi Kawai(neuecc)\n\nWhat is UniRx?\n---\nUniRx (Reactive Extensions for Unity) is a reimplementation of the .NET Reactive Extensions. The Official Rx implementation is great but doesn't work on Unity and has issues with iOS IL2CPP compatibility. This library fixes those issues and adds some specific utilities for Unity. Supported platforms are PC/Mac/Android/iOS/WebGL/WindowsStore/etc and the library.\n\nUniRx is available on the Unity Asset Store (FREE) - http://u3d.as/content/neuecc/uni-rx-reactive-extensions-for-unity/7tT\n\nBlog for update info - https://medium.com/@neuecc\n\nSupport thread on the Unity Forums: Ask me any question - http://forum.unity3d.com/threads/248535-UniRx-Reactive-Extensions-for-Unity\n\nRelease Notes, see [UniRx/releases](https://github.com/neuecc/UniRx/releases)\n\nUniRx is Core Library (Port of Rx) + Platform Adaptor (MainThreadScheduler/FromCoroutine/etc) + Framework (ObservableTriggers/ReactiveProeperty/etc).\n\n\u003e Note: async/await integration(UniRx.Async) is separated to [Cysharp/UniTask](https://github.com/Cysharp/UniTask) after ver. 7.0.\n\nWhy Rx?\n---\nOrdinarily, Network operations in Unity require the use of `WWW` and `Coroutine`. That said, using `Coroutine` is not good practice for asynchronous operations for the following (and other) reasons:\n\n1. Coroutines can't return any values, since its return type must be IEnumerator.\n2. Coroutines can't handle exceptions, because yield return statements cannot be surrounded with a try-catch construction.\n\nThis kind of lack of composability causes operations to be close-coupled, which often results in huge monolithic IEnumerators.\n\nRx cures that kind of \"asynchronous blues\". Rx is a library for composing asynchronous and event-based programs using observable collections and LINQ-style query operators. \n  \nThe game loop (every Update, OnCollisionEnter, etc), sensor data (Kinect, Leap Motion, VR Input, etc.) are all types of events. Rx represents events as reactive sequences which are both easily composable and support time-based operations by using LINQ query operators.\n\nUnity is generally single threaded but UniRx facilitates multithreading for joins, cancels, accessing GameObjects, etc.\n\nUniRx helps UI programming with uGUI. All UI events (clicked, valuechanged, etc) can be converted to UniRx event streams. \n\nUnity supports async/await from 2017 with C# upgrades, UniRx family prjects provides more lightweight, more powerful async/await integration with Unity. Please see  [Cysharp/UniTask](https://github.com/Cysharp/UniTask).\n\nIntroduction\n---\nGreat introduction to Rx article: [The introduction to Reactive Programming you've been missing](https://gist.github.com/staltz/868e7e9bc2a7b8c1f754).\n\nThe following code implements the double click detection example from the article in UniRx:\n\n```csharp\nvar clickStream = Observable.EveryUpdate()\n    .Where(_ =\u003e Input.GetMouseButtonDown(0));\n\nclickStream.Buffer(clickStream.Throttle(TimeSpan.FromMilliseconds(250)))\n    .Where(xs =\u003e xs.Count \u003e= 2)\n    .Subscribe(xs =\u003e Debug.Log(\"DoubleClick Detected! Count:\" + xs.Count));\n```\n\nThis example demonstrates the following features (in only five lines!):\n\n* The game loop (Update) as an event stream\n* Composable event streams\n* Merging self stream\n* Easy handling of time based operations   \n\nNetwork operations\n---\nUse ObservableWWW for asynchronous network operations. Its Get/Post functions return subscribable IObservables:\n\n```csharp\nObservableWWW.Get(\"http://google.co.jp/\")\n    .Subscribe(\n        x =\u003e Debug.Log(x.Substring(0, 100)), // onSuccess\n        ex =\u003e Debug.LogException(ex)); // onError\n```\n\nRx is composable and cancelable. You can also query with LINQ expressions:\n\n```csharp\n// composing asynchronous sequence with LINQ query expressions\nvar query = from google in ObservableWWW.Get(\"http://google.com/\")\n            from bing in ObservableWWW.Get(\"http://bing.com/\")\n            from unknown in ObservableWWW.Get(google + bing)\n            select new { google, bing, unknown };\n\nvar cancel = query.Subscribe(x =\u003e Debug.Log(x));\n\n// Call Dispose is cancel.\ncancel.Dispose();\n```\n\nUse Observable.WhenAll for parallel requests:\n\n```csharp\n// Observable.WhenAll is for parallel asynchronous operation\n// (It's like Observable.Zip but specialized for single async operations like Task.WhenAll)\nvar parallel = Observable.WhenAll(\n    ObservableWWW.Get(\"http://google.com/\"),\n    ObservableWWW.Get(\"http://bing.com/\"),\n    ObservableWWW.Get(\"http://unity3d.com/\"));\n\nparallel.Subscribe(xs =\u003e\n{\n    Debug.Log(xs[0].Substring(0, 100)); // google\n    Debug.Log(xs[1].Substring(0, 100)); // bing\n    Debug.Log(xs[2].Substring(0, 100)); // unity\n});\n```\n\nProgress information is available:\n\n```csharp\n// notifier for progress use ScheduledNotifier or new Progress\u003cfloat\u003e(/* action */)\nvar progressNotifier = new ScheduledNotifier\u003cfloat\u003e();\nprogressNotifier.Subscribe(x =\u003e Debug.Log(x)); // write www.progress\n\n// pass notifier to WWW.Get/Post\nObservableWWW.Get(\"http://google.com/\", progress: progressNotifier).Subscribe();\n```\n\nError handling:\n\n```csharp\n// If WWW has .error, ObservableWWW throws WWWErrorException to onError pipeline.\n// WWWErrorException has RawErrorMessage, HasResponse, StatusCode, ResponseHeaders\nObservableWWW.Get(\"http://www.google.com/404\")\n    .CatchIgnore((WWWErrorException ex) =\u003e\n    {\n        Debug.Log(ex.RawErrorMessage);\n        if (ex.HasResponse)\n        {\n            Debug.Log(ex.StatusCode);\n        }\n        foreach (var item in ex.ResponseHeaders)\n        {\n            Debug.Log(item.Key + \":\" + item.Value);\n        }\n    })\n    .Subscribe();\n```\n\nUsing with IEnumerators (Coroutines)\n---\nIEnumerator (Coroutine) is Unity's primitive asynchronous tool. UniRx integrates coroutines and IObservables. You can write asynchronious code in coroutines, and orchestrate them using UniRx. This is best way to control asynchronous flow.\n\n```csharp\n// two coroutines\n\nIEnumerator AsyncA()\n{\n    Debug.Log(\"a start\");\n    yield return new WaitForSeconds(1);\n    Debug.Log(\"a end\");\n}\n\nIEnumerator AsyncB()\n{\n    Debug.Log(\"b start\");\n    yield return new WaitForEndOfFrame();\n    Debug.Log(\"b end\");\n}\n\n// main code\n// Observable.FromCoroutine converts IEnumerator to Observable\u003cUnit\u003e.\n// You can also use the shorthand, AsyncA().ToObservable()\n        \n// after AsyncA completes, run AsyncB as a continuous routine.\n// UniRx expands SelectMany(IEnumerator) as SelectMany(IEnumerator.ToObservable())\nvar cancel = Observable.FromCoroutine(AsyncA)\n    .SelectMany(AsyncB)\n    .Subscribe();\n\n// you can stop a coroutine by calling your subscription's Dispose.\ncancel.Dispose();\n```\n\nIf in Unity 5.3, you can use ToYieldInstruction for Observable to Coroutine.\n\n```csharp\nIEnumerator TestNewCustomYieldInstruction()\n{\n    // wait Rx Observable.\n    yield return Observable.Timer(TimeSpan.FromSeconds(1)).ToYieldInstruction();\n\n    // you can change the scheduler(this is ignore Time.scale)\n    yield return Observable.Timer(TimeSpan.FromSeconds(1), Scheduler.MainThreadIgnoreTimeScale).ToYieldInstruction();\n\n    // get return value from ObservableYieldInstruction\n    var o = ObservableWWW.Get(\"http://unity3d.com/\").ToYieldInstruction(throwOnError: false);\n    yield return o;\n\n    if (o.HasError) { Debug.Log(o.Error.ToString()); }\n    if (o.HasResult) { Debug.Log(o.Result); }\n\n    // other sample(wait until transform.position.y \u003e= 100) \n    yield return this.transform.ObserveEveryValueChanged(x =\u003e x.position).FirstOrDefault(p =\u003e p.y \u003e= 100).ToYieldInstruction();\n}\n```\nNormally, we have to use callbacks when we require a coroutine to return a value. Observable.FromCoroutine can convert coroutines to cancellable IObservable[T] instead.\n\n```csharp\n// public method\npublic static IObservable\u003cstring\u003e GetWWW(string url)\n{\n    // convert coroutine to IObservable\n    return Observable.FromCoroutine\u003cstring\u003e((observer, cancellationToken) =\u003e GetWWWCore(url, observer, cancellationToken));\n}\n\n// IObserver is a callback publisher\n// Note: IObserver's basic scheme is \"OnNext* (OnError | Oncompleted)?\" \nstatic IEnumerator GetWWWCore(string url, IObserver\u003cstring\u003e observer, CancellationToken cancellationToken)\n{\n    var www = new UnityEngine.WWW(url);\n    while (!www.isDone \u0026\u0026 !cancellationToken.IsCancellationRequested)\n    {\n        yield return null;\n    }\n\n    if (cancellationToken.IsCancellationRequested) yield break;\n\n    if (www.error != null)\n    {\n        observer.OnError(new Exception(www.error));\n    }\n    else\n    {\n        observer.OnNext(www.text);\n        observer.OnCompleted(); // IObserver needs OnCompleted after OnNext!\n    }\n}\n```\n\nHere are some more examples. Next is a multiple OnNext pattern.\n\n```csharp\npublic static IObservable\u003cfloat\u003e ToObservable(this UnityEngine.AsyncOperation asyncOperation)\n{\n    if (asyncOperation == null) throw new ArgumentNullException(\"asyncOperation\");\n\n    return Observable.FromCoroutine\u003cfloat\u003e((observer, cancellationToken) =\u003e RunAsyncOperation(asyncOperation, observer, cancellationToken));\n}\n\nstatic IEnumerator RunAsyncOperation(UnityEngine.AsyncOperation asyncOperation, IObserver\u003cfloat\u003e observer, CancellationToken cancellationToken)\n{\n    while (!asyncOperation.isDone \u0026\u0026 !cancellationToken.IsCancellationRequested)\n    {\n        observer.OnNext(asyncOperation.progress);\n        yield return null;\n    }\n    if (!cancellationToken.IsCancellationRequested)\n    {\n        observer.OnNext(asyncOperation.progress); // push 100%\n        observer.OnCompleted();\n    }\n}\n\n// usecase\nApplication.LoadLevelAsync(\"testscene\")\n    .ToObservable()\n    .Do(x =\u003e Debug.Log(x)) // output progress\n    .Last() // last sequence is load completed\n    .Subscribe();\n```\n\nUsing for MultiThreading\n---\n\n```csharp\n// Observable.Start is start factory methods on specified scheduler\n// default is on ThreadPool\nvar heavyMethod = Observable.Start(() =\u003e\n{\n    // heavy method...\n    System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));\n    return 10;\n});\n\nvar heavyMethod2 = Observable.Start(() =\u003e\n{\n    // heavy method...\n    System.Threading.Thread.Sleep(TimeSpan.FromSeconds(3));\n    return 10;\n});\n\n// Join and await two other thread values\nObservable.WhenAll(heavyMethod, heavyMethod2)\n    .ObserveOnMainThread() // return to main thread\n    .Subscribe(xs =\u003e\n    {\n        // Unity can't touch GameObject from other thread\n        // but use ObserveOnMainThread, you can touch GameObject naturally.\n        (GameObject.Find(\"myGuiText\")).guiText.text = xs[0] + \":\" + xs[1];\n    }); \n```\n\nDefaultScheduler\n---\nUniRx's default time based operations (Interval, Timer, Buffer(timeSpan), etc) use `Scheduler.MainThread` as their scheduler. That means most operators (except for `Observable.Start`) work on a single thread, so ObserverOn isn't needed and thread safety measures can be ignored. This is differet from the standard RxNet implementation but better suited to the Unity environment.  \n\n`Scheduler.MainThread` runs under Time.timeScale's influence. If you want to ignore the time scale, use ` Scheduler.MainThreadIgnoreTimeScale` instead.\n\nMonoBehaviour triggers\n---\nUniRx can handle MonoBehaviour events with `UniRx.Triggers`:\n\n```csharp\nusing UniRx;\nusing UniRx.Triggers; // need UniRx.Triggers namespace\n\npublic class MyComponent : MonoBehaviour\n{\n    void Start()\n    {\n        // Get the plain object\n        var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);\n\n        // Add ObservableXxxTrigger for handle MonoBehaviour's event as Observable\n        cube.AddComponent\u003cObservableUpdateTrigger\u003e()\n            .UpdateAsObservable()\n            .SampleFrame(30)\n            .Subscribe(x =\u003e Debug.Log(\"cube\"), () =\u003e Debug.Log(\"destroy\"));\n\n        // destroy after 3 second:)\n        GameObject.Destroy(cube, 3f);\n    }\n}\n```\n\nSupported triggers are listed in [UniRx.wiki#UniRx.Triggers](https://github.com/neuecc/UniRx/wiki#unirxtriggers).\n\nThese can also be handled more easily by directly subscribing to observables returned by extension methods on Component/GameObject. These methods inject ObservableTrigger automaticaly (except for `ObservableEventTrigger` and `ObservableStateMachineTrigger`):\n\n```csharp\nusing UniRx;\nusing UniRx.Triggers; // need UniRx.Triggers namespace for extend gameObejct\n\npublic class DragAndDropOnce : MonoBehaviour\n{\n    void Start()\n    {\n        // All events can subscribe by ***AsObservable\n        this.OnMouseDownAsObservable()\n            .SelectMany(_ =\u003e this.UpdateAsObservable())\n            .TakeUntil(this.OnMouseUpAsObservable())\n            .Select(_ =\u003e Input.mousePosition)\n            .Subscribe(x =\u003e Debug.Log(x));\n    }\n}\n```\n\n\u003e Previous versions of UniRx provided `ObservableMonoBehaviour`. This is a legacy interface that is no longer supported. Please use UniRx.Triggers instead.\n\nCreating custom triggers\n---\nConverting to Observable is the best way to handle Unity events. If the standard triggers supplied by UniRx are not enough, you can create custom triggers. To demonstrate, here's a LongTap trigger for uGUI:\n\n```csharp\npublic class ObservableLongPointerDownTrigger : ObservableTriggerBase, IPointerDownHandler, IPointerUpHandler\n{\n    public float IntervalSecond = 1f;\n\n    Subject\u003cUnit\u003e onLongPointerDown;\n\n    float? raiseTime;\n\n    void Update()\n    {\n        if (raiseTime != null \u0026\u0026 raiseTime \u003c= Time.realtimeSinceStartup)\n        {\n            if (onLongPointerDown != null) onLongPointerDown.OnNext(Unit.Default);\n            raiseTime = null;\n        }\n    }\n\n    void IPointerDownHandler.OnPointerDown(PointerEventData eventData)\n    {\n        raiseTime = Time.realtimeSinceStartup + IntervalSecond;\n    }\n\n    void IPointerUpHandler.OnPointerUp(PointerEventData eventData)\n    {\n        raiseTime = null;\n    }\n\n    public IObservable\u003cUnit\u003e OnLongPointerDownAsObservable()\n    {\n        return onLongPointerDown ?? (onLongPointerDown = new Subject\u003cUnit\u003e());\n    }\n\n    protected override void RaiseOnCompletedOnDestroy()\n    {\n        if (onLongPointerDown != null)\n        {\n            onLongPointerDown.OnCompleted();\n        }\n    }\n}\n```\n\nIt can be used as easily as the standard triggers:\n\n```csharp\nvar trigger = button.AddComponent\u003cObservableLongPointerDownTrigger\u003e();\n\ntrigger.OnLongPointerDownAsObservable().Subscribe();\n```\n\nObservable Lifecycle Management\n---\nWhen is OnCompleted called? Subscription lifecycle management is very important to consider when using UniRx. `ObservableTriggers` call OnCompleted when the GameObject they are attached to is destroyed. Other static generator methods (`Observable.Timer`, `Observable.EveryUpdate`, etc...) do not stop automatically, and their subscriptions should be managed manually.\n\nRx provides some helper methods, such as `IDisposable.AddTo` which allows you to dispose of several subscriptions at once:\n\n```csharp\n// CompositeDisposable is similar with List\u003cIDisposable\u003e, manage multiple IDisposable\nCompositeDisposable disposables = new CompositeDisposable(); // field\n\nvoid Start()\n{\n    Observable.EveryUpdate().Subscribe(x =\u003e Debug.Log(x)).AddTo(disposables);\n}\n\nvoid OnTriggerEnter(Collider other)\n{\n    // .Clear() =\u003e Dispose is called for all inner disposables, and the list is cleared.\n    // .Dispose() =\u003e Dispose is called for all inner disposables, and Dispose is called immediately after additional Adds.\n    disposables.Clear();\n}\n```\n\nIf you want to automatically Dispose when a GameObjects is destroyed, use AddTo(GameObject/Component):\n\n```csharp\nvoid Start()\n{\n    Observable.IntervalFrame(30).Subscribe(x =\u003e Debug.Log(x)).AddTo(this);\n}\n```\n\nAddTo calls facilitate automatic Dispose. If you needs special OnCompleted handling in the pipeline, however, use `TakeWhile`, `TakeUntil`, `TakeUntilDestroy` and `TakeUntilDisable` instead:\n\n```csharp\nObservable.IntervalFrame(30).TakeUntilDisable(this)\n    .Subscribe(x =\u003e Debug.Log(x), () =\u003e Debug.Log(\"completed!\"));\n```\n\nIf you handle events, `Repeat` is an important but dangerous method. It may cause an infinite loop, so handle with care:\n\n```csharp\nusing UniRx;\nusing UniRx.Triggers;\n\npublic class DangerousDragAndDrop : MonoBehaviour\n{\n    void Start()\n    {\n        this.gameObject.OnMouseDownAsObservable()\n            .SelectMany(_ =\u003e this.gameObject.UpdateAsObservable())\n            .TakeUntil(this.gameObject.OnMouseUpAsObservable())\n            .Select(_ =\u003e Input.mousePosition)\n            .Repeat() // dangerous!!! Repeat cause infinite repeat subscribe at GameObject was destroyed.(If in UnityEditor, Editor is freezed)\n            .Subscribe(x =\u003e Debug.Log(x));\n    }\n}\n```\n\nUniRx provides an additional safe Repeat method. `RepeatSafe`: if contiguous \"OnComplete\" are called repeat stops. `RepeatUntilDestroy(gameObject/component)`, `RepeatUntilDisable(gameObject/component)` allows to stop when a target GameObject has been destroyed:\n\n```csharp\nthis.gameObject.OnMouseDownAsObservable()\n    .SelectMany(_ =\u003e this.gameObject.UpdateAsObservable())\n    .TakeUntil(this.gameObject.OnMouseUpAsObservable())\n    .Select(_ =\u003e Input.mousePosition)\n    .RepeatUntilDestroy(this) // safety way\n    .Subscribe(x =\u003e Debug.Log(x));            \n```\n\nUniRx gurantees hot observable(FromEvent/Subject/ReactiveProperty/UnityUI.AsObservable..., there are like event) have unhandled exception durability. What is it? If subscribe in subcribe, does not detach event.\n\n```csharp\nbutton.OnClickAsObservable().Subscribe(_ =\u003e\n{\n    // If throws error in inner subscribe, but doesn't detached OnClick event.\n    ObservableWWW.Get(\"htttp://error/\").Subscribe(x =\u003e\n    {\n        Debug.Log(x);\n    });\n});\n```\n\nThis behaviour is sometimes useful such as user event handling.\n\n\nAll class instances provide an `ObserveEveryValueChanged` method, which watches for changing values every frame:\n\n```csharp\n// watch position change\nthis.transform.ObserveEveryValueChanged(x =\u003e x.position).Subscribe(x =\u003e Debug.Log(x));\n```\n\nIt's very useful. If the watch target is a GameObject, it will stop observing when the target is destroyed, and call OnCompleted. If the watch target is a plain C# Object, OnCompleted will be called on GC.\n\nConverting Unity callbacks to IObservables\n---\nUse Subject (or AsyncSubject for asynchronious operations):\n\n```csharp\npublic class LogCallback\n{\n    public string Condition;\n    public string StackTrace;\n    public UnityEngine.LogType LogType;\n}\n\npublic static class LogHelper\n{\n    static Subject\u003cLogCallback\u003e subject;\n\n    public static IObservable\u003cLogCallback\u003e LogCallbackAsObservable()\n    {\n        if (subject == null)\n        {\n            subject = new Subject\u003cLogCallback\u003e();\n\n            // Publish to Subject in callback\n            UnityEngine.Application.RegisterLogCallback((condition, stackTrace, type) =\u003e\n            {\n                subject.OnNext(new LogCallback { Condition = condition, StackTrace = stackTrace, LogType = type });\n            });\n        }\n\n        return subject.AsObservable();\n    }\n}\n\n// method is separatable and composable\nLogHelper.LogCallbackAsObservable()\n    .Where(x =\u003e x.LogType == LogType.Warning)\n    .Subscribe();\n\nLogHelper.LogCallbackAsObservable()\n    .Where(x =\u003e x.LogType == LogType.Error)\n    .Subscribe();\n```\n\nIn Unity5, `Application.RegisterLogCallback` was removed in favor of `Application.logMessageReceived`, so we can now simply use `Observable.FromEvent`.\n\n```csharp\npublic static IObservable\u003cLogCallback\u003e LogCallbackAsObservable()\n{\n    return Observable.FromEvent\u003cApplication.LogCallback, LogCallback\u003e(\n        h =\u003e (condition, stackTrace, type) =\u003e h(new LogCallback { Condition = condition, StackTrace = stackTrace, LogType = type }),\n        h =\u003e Application.logMessageReceived += h, h =\u003e Application.logMessageReceived -= h);\n}\n```\n\nStream Logger\n---\n```csharp\n// using UniRx.Diagnostics;\n\n// logger is threadsafe, define per class with name.\nstatic readonly Logger logger = new Logger(\"Sample11\");\n\n// call once at applicationinit\npublic static void ApplicationInitialize()\n{\n    // Log as Stream, UniRx.Diagnostics.ObservableLogger.Listener is IObservable\u003cLogEntry\u003e\n    // You can subscribe and output to any place.\n    ObservableLogger.Listener.LogToUnityDebug();\n\n    // for example, filter only Exception and upload to web.\n    // (make custom sink(IObserver\u003cEventEntry\u003e) is better to use)\n    ObservableLogger.Listener\n        .Where(x =\u003e x.LogType == LogType.Exception)\n        .Subscribe(x =\u003e\n        {\n            // ObservableWWW.Post(\"\", null).Subscribe();\n        });\n}\n\n// Debug is write only DebugBuild.\nlogger.Debug(\"Debug Message\");\n\n// or other logging methods\nlogger.Log(\"Message\");\nlogger.Exception(new Exception(\"test exception\"));\n```\n\nDebugging\n---\n`Debug` operator in `UniRx.Diagnostics` namespace helps debugging.\n\n```csharp\n// needs Diagnostics using\nusing UniRx.Diagnostics;\n\n---\n\n// [DebugDump, Normal]OnSubscribe\n// [DebugDump, Normal]OnNext(1)\n// [DebugDump, Normal]OnNext(10)\n// [DebugDump, Normal]OnCompleted()\n{\n    var subject = new Subject\u003cint\u003e();\n\n    subject.Debug(\"DebugDump, Normal\").Subscribe();\n\n    subject.OnNext(1);\n    subject.OnNext(10);\n    subject.OnCompleted();\n}\n\n// [DebugDump, Cancel]OnSubscribe\n// [DebugDump, Cancel]OnNext(1)\n// [DebugDump, Cancel]OnCancel\n{\n    var subject = new Subject\u003cint\u003e();\n\n    var d = subject.Debug(\"DebugDump, Cancel\").Subscribe();\n\n    subject.OnNext(1);\n    d.Dispose();\n}\n\n// [DebugDump, Error]OnSubscribe\n// [DebugDump, Error]OnNext(1)\n// [DebugDump, Error]OnError(System.Exception)\n{\n    var subject = new Subject\u003cint\u003e();\n\n    subject.Debug(\"DebugDump, Error\").Subscribe();\n\n    subject.OnNext(1);\n    subject.OnError(new Exception());\n}\n```\n\nshows sequence element on `OnNext`, `OnError`, `OnCompleted`, `OnCancel`, `OnSubscribe` timing to Debug.Log. It enables only `#if DEBUG`.\n\nUnity-specific Extra Gems\n---\n```csharp\n// Unity's singleton UiThread Queue Scheduler\nScheduler.MainThreadScheduler \nObserveOnMainThread()/SubscribeOnMainThread()\n\n// Global StartCoroutine runner\nMainThreadDispatcher.StartCoroutine(enumerator)\n\n// convert Coroutine to IObservable\nObservable.FromCoroutine((observer, token) =\u003e enumerator(observer, token)); \n\n// convert IObservable to Coroutine\nyield return Observable.Range(1, 10).ToYieldInstruction(); // after Unity 5.3, before can use StartAsCoroutine()\n\n// Lifetime hooks\nObservable.EveryApplicationPause();\nObservable.EveryApplicationFocus();\nObservable.OnceApplicationQuit();\n```\n\nFramecount-based time operators\n---\nUniRx provides a few framecount-based time operators:\n\nMethod | \n-------|\nEveryUpdate|\nEveryFixedUpdate|\nEveryEndOfFrame|\nEveryGameObjectUpdate|\nEveryLateUpdate|\nObserveOnMainThread|\nNextFrame|\nIntervalFrame|\nTimerFrame|\nDelayFrame|\nSampleFrame|\nThrottleFrame|\nThrottleFirstFrame|\nTimeoutFrame|\nDelayFrameSubscription|\nFrameInterval|\nFrameTimeInterval|\nBatchFrame|\n\nFor example, delayed invoke once:\n\n```csharp\nObservable.TimerFrame(100).Subscribe(_ =\u003e Debug.Log(\"after 100 frame\"));\n```\n\nEvery* Method's execution order is\n\n```\nEveryGameObjectUpdate(in MainThreadDispatcher's Execution Order) -\u003e\nEveryUpdate -\u003e \nEveryLateUpdate -\u003e \nEveryEndOfFrame\n```\n\nEveryGameObjectUpdate invoke from same frame if caller is called before MainThreadDispatcher.Update(I recommend MainThreadDispatcher called first than others(ScriptExecutionOrder makes -32000)      \nEveryLateUpdate, EveryEndOfFrame invoke from same frame.  \nEveryUpdate, invoke from next frame.  \n\nMicroCoroutine\n---\nMicroCoroutine is memory efficient and fast coroutine worker. This implemantation is based on [Unity blog's 10000 UPDATE() CALLS](http://blogs.unity3d.com/2015/12/23/1k-update-calls/), avoid managed-unmanaged overhead so gets 10x faster iteration. MicroCoroutine is automaticaly used on Framecount-based time operators and ObserveEveryValueChanged.\n\nIf you want to use MicroCoroutine instead of standard unity coroutine, use `MainThreadDispatcher.StartUpdateMicroCoroutine` or `Observable.FromMicroCoroutine`.\n\n```csharp\nint counter;\n\nIEnumerator Worker()\n{\n    while(true)\n    {\n        counter++;\n        yield return null;\n    }\n}\n\nvoid Start()\n{\n    for(var i = 0; i \u003c 10000; i++)\n    {\n        // fast, memory efficient\n        MainThreadDispatcher.StartUpdateMicroCoroutine(Worker());\n\n        // slow...\n        // StartCoroutine(Worker());\n    }\n}\n```\n\n![image](https://cloud.githubusercontent.com/assets/46207/15267997/86e9ed5c-1a0c-11e6-8371-14b61a09c72c.png)\n\nMicroCoroutine's limitation, only supports `yield return null` and update timing is determined start method(`StartUpdateMicroCoroutine`, `StartFixedUpdateMicroCoroutine`, `StartEndOfFrameMicroCoroutine`). \n\nIf you combine with other IObservable, you can check completed property like isDone.\n\n```csharp\nIEnumerator MicroCoroutineWithToYieldInstruction()\n{\n    var www = ObservableWWW.Get(\"http://aaa\").ToYieldInstruction();\n    while (!www.IsDone)\n    {\n        yield return null;\n    }\n\n    if (www.HasResult)\n    {\n        UnityEngine.Debug.Log(www.Result);\n    }\n}\n```\n\nuGUI Integration\n---\nUniRx can handle `UnityEvent`s easily. Use `UnityEvent.AsObservable` to subscribe to events:\n\n```csharp\npublic Button MyButton;\n// ---\nMyButton.onClick.AsObservable().Subscribe(_ =\u003e Debug.Log(\"clicked\"));\n```\n\nTreating Events as Observables enables declarative UI programming. \n\n```csharp\npublic Toggle MyToggle;\npublic InputField MyInput;\npublic Text MyText;\npublic Slider MySlider;\n\n// On Start, you can write reactive rules for declaretive/reactive ui programming\nvoid Start()\n{\n    // Toggle, Input etc as Observable (OnValueChangedAsObservable is a helper providing isOn value on subscribe)\n    // SubscribeToInteractable is an Extension Method, same as .interactable = x)\n    MyToggle.OnValueChangedAsObservable().SubscribeToInteractable(MyButton);\n    \n    // Input is displayed after a 1 second delay\n    MyInput.OnValueChangedAsObservable()\n        .Where(x =\u003e x != null)\n        .Delay(TimeSpan.FromSeconds(1))\n        .SubscribeToText(MyText); // SubscribeToText is helper for subscribe to text\n    \n    // Converting for human readability\n    MySlider.OnValueChangedAsObservable()\n        .SubscribeToText(MyText, x =\u003e Math.Round(x, 2).ToString());\n}\n```\n\nFor more on reactive UI programming please consult Sample12, Sample13 and the ReactiveProperty section below. \n\nReactiveProperty, ReactiveCollection\n---\nGame data often requires notification. Should we use properties and events (callbacks)? That's often too complex. UniRx provides ReactiveProperty, a lightweight property broker.\n\n```csharp\n// Reactive Notification Model\npublic class Enemy\n{\n    public ReactiveProperty\u003clong\u003e CurrentHp { get; private set; }\n\n    public ReactiveProperty\u003cbool\u003e IsDead { get; private set; }\n\n    public Enemy(int initialHp)\n    {\n        // Declarative Property\n        CurrentHp = new ReactiveProperty\u003clong\u003e(initialHp);\n        IsDead = CurrentHp.Select(x =\u003e x \u003c= 0).ToReactiveProperty();\n    }\n}\n\n// ---\n// onclick, HP decrement\nMyButton.OnClickAsObservable().Subscribe(_ =\u003e enemy.CurrentHp.Value -= 99);\n// subscribe from notification model.\nenemy.CurrentHp.SubscribeToText(MyText);\nenemy.IsDead.Where(isDead =\u003e isDead == true)\n    .Subscribe(_ =\u003e\n    {\n        MyButton.interactable = false;\n    });\n```\n\nYou can combine ReactiveProperties, ReactiveCollections and observables returned by UnityEvent.AsObservable. All UI elements are observable.\n\nGeneric ReactiveProperties are not serializable or inspecatble in the Unity editor, but UniRx provides specialized subclasses of ReactiveProperty that are. These include classes such as Int/LongReactiveProperty, Float/DoubleReactiveProperty, StringReactiveProperty, BoolReactiveProperty and more (Browse them here: [InspectableReactiveProperty.cs](https://github.com/neuecc/UniRx/blob/master/Assets/Plugins/UniRx/Scripts/UnityEngineBridge/InspectableReactiveProperty.cs)). All are fully editable in the inspector. For custom Enum ReactiveProperty, it's easy to write a custom inspectable ReactiveProperty[T].\n\nIf you needs `[Multiline]` or `[Range]` attach to ReactiveProperty, you can use `MultilineReactivePropertyAttribute` and `RangeReactivePropertyAttribute` instead of `Multiline` and `Range`.\n\nThe provided derived InpsectableReactiveProperties are displayed in the inspector naturally and notify when their value is changed even when it is changed in the inspector.\n\n![](StoreDocument/RxPropInspector.png)\n\nThis functionality is provided by [InspectorDisplayDrawer](https://github.com/neuecc/UniRx/blob/master/Assets/Plugins/UniRx/Scripts/UnityEngineBridge/InspectorDisplayDrawer.cs). You can supply your own custom specialized ReactiveProperties by inheriting from it:\n\n```csharp\npublic enum Fruit\n{\n    Apple, Grape\n}\n\n[Serializable]\npublic class FruitReactiveProperty : ReactiveProperty\u003cFruit\u003e\n{\n    public FruitReactiveProperty()\n    {\n    }\n\n    public FruitReactiveProperty(Fruit initialValue)\n        :base(initialValue)\n    {\n    }\n}\n\n[UnityEditor.CustomPropertyDrawer(typeof(FruitReactiveProperty))]\n[UnityEditor.CustomPropertyDrawer(typeof(YourSpecializedReactiveProperty2))] // and others...\npublic class ExtendInspectorDisplayDrawer : InspectorDisplayDrawer\n{\n}\n```\n\nIf a ReactiveProperty value is only updated within a stream, you can make it read only by using from `ReadOnlyReactiveProperty`.\n\n```csharp\npublic class Person\n{\n    public ReactiveProperty\u003cstring\u003e GivenName { get; private set; }\n    public ReactiveProperty\u003cstring\u003e FamilyName { get; private set; }\n    public ReadOnlyReactiveProperty\u003cstring\u003e FullName { get; private set; }\n\n    public Person(string givenName, string familyName)\n    {\n        GivenName = new ReactiveProperty\u003cstring\u003e(givenName);\n        FamilyName = new ReactiveProperty\u003cstring\u003e(familyName);\n        // If change the givenName or familyName, notify with fullName!\n        FullName = GivenName.CombineLatest(FamilyName, (x, y) =\u003e x + \" \" + y).ToReadOnlyReactiveProperty();\n    }\n}\n```\n\nModel-View-(Reactive)Presenter Pattern\n---\nUniRx makes it possible to implement the MVP(MVRP) Pattern.\n\n![](StoreDocument/MVP_Pattern.png)\n\nWhy should we use MVP instead of MVVM? Unity doesn't provide a UI binding mechanism and creating a binding layer is too complex and loss and affects performance. Still, Views need updating. Presenters are aware of their view's components and can update them. Although there is no real binding, Observables enables subscription to notification, which can act much like the real thing. This pattern is called a Reactive Presenter: \n\n```csharp\n// Presenter for scene(canvas) root.\npublic class ReactivePresenter : MonoBehaviour\n{\n    // Presenter is aware of its View (binded in the inspector)\n    public Button MyButton;\n    public Toggle MyToggle;\n    \n    // State-Change-Events from Model by ReactiveProperty\n    Enemy enemy = new Enemy(1000);\n\n    void Start()\n    {\n        // Rx supplies user events from Views and Models in a reactive manner \n        MyButton.OnClickAsObservable().Subscribe(_ =\u003e enemy.CurrentHp.Value -= 99);\n        MyToggle.OnValueChangedAsObservable().SubscribeToInteractable(MyButton);\n\n        // Models notify Presenters via Rx, and Presenters update their views\n        enemy.CurrentHp.SubscribeToText(MyText);\n        enemy.IsDead.Where(isDead =\u003e isDead == true)\n            .Subscribe(_ =\u003e\n            {\n                MyToggle.interactable = MyButton.interactable = false;\n            });\n    }\n}\n\n// The Model. All property notify when their values change\npublic class Enemy\n{\n    public ReactiveProperty\u003clong\u003e CurrentHp { get; private set; }\n\n    public ReactiveProperty\u003cbool\u003e IsDead { get; private set; }\n\n    public Enemy(int initialHp)\n    {\n        // Declarative Property\n        CurrentHp = new ReactiveProperty\u003clong\u003e(initialHp);\n        IsDead = CurrentHp.Select(x =\u003e x \u003c= 0).ToReactiveProperty();\n    }\n}\n```\n\nA View is a scene, that is a Unity hierarchy. Views are associated with Presenters by the Unity Engine on initialize. The XxxAsObservable methods make creating event signals simple, without any overhead. SubscribeToText and SubscribeToInteractable are simple binding-like helpers. These may be simple tools, but they are very powerful. They feel natural in the Unity environment and provide high performance and a clean architecture.\n\n![](StoreDocument/MVRP_Loop.png)\n\nV -\u003e RP -\u003e M -\u003e RP -\u003e V completely connected in a reactive way. UniRx provides all of the adaptor methods and classes, but other MVVM(or MV*) frameworks can be used instead. UniRx/ReactiveProperty is only simple toolkit. \n\nGUI programming also benefits from ObservableTriggers. ObservableTriggers convert Unity events to Observables, so the MV(R)P pattern can be composed using them. For example, `ObservableEventTrigger` converts uGUI events to Observable:\n\n```csharp\nvar eventTrigger = this.gameObject.AddComponent\u003cObservableEventTrigger\u003e();\neventTrigger.OnBeginDragAsObservable()\n    .SelectMany(_ =\u003e eventTrigger.OnDragAsObservable(), (start, current) =\u003e UniRx.Tuple.Create(start, current))\n    .TakeUntil(eventTrigger.OnEndDragAsObservable())\n    .RepeatUntilDestroy(this)\n    .Subscribe(x =\u003e Debug.Log(x));\n```\n\n(Obsolete)PresenterBase\n---\n\u003e Note:\n\u003e PresenterBase works enough, but too complex.  \n\u003e You can use simple `Initialize` method and call parent to child, it works for most scenario.  \n\u003e So I don't recommend using `PresenterBase`, sorry.   \n\nReactiveCommand, AsyncReactiveCommand\n----\nReactiveCommand abstraction of button command with boolean interactable.\n             \n```csharp\npublic class Player\n{\t\t\n   public ReactiveProperty\u003cint\u003e Hp;\t\t\n   public ReactiveCommand Resurrect;\t\t\n\t\t\n   public Player()\n   {\t\t\n        Hp = new ReactiveProperty\u003cint\u003e(1000);\t\t\n        \t\t\n        // If dead, can not execute.\t\t\n        Resurrect = Hp.Select(x =\u003e x \u003c= 0).ToReactiveCommand();\t\t\n        // Execute when clicked\t\t\n        Resurrect.Subscribe(_ =\u003e\t\t\n        {\t\t\n             Hp.Value = 1000;\t\t\n        }); \t\t\n    }\t\t\n}\t\t\n\t\t\npublic class Presenter : MonoBehaviour\t\t\n{\t\t\n    public Button resurrectButton;\t\t\n\t\t\n    Player player;\t\t\n\t\t\n    void Start()\n    {\t\t\n      player = new Player();\t\t\n\t\t\n      // If Hp \u003c= 0, can't press button.\t\t\n      player.Resurrect.BindTo(resurrectButton);\t\t\n    }\t\t\n}\t\t\n```\t\t\n\t\t\nAsyncReactiveCommand is a variation of ReactiveCommand that `CanExecute`(in many cases bind to button's interactable) is changed to false until asynchronous execution was finished.\t\t\n\t\t\n```csharp\t\t\npublic class Presenter : MonoBehaviour\t\t\n{\t\t\n    public UnityEngine.UI.Button button;\t\t\n\t\t\n    void Start()\n    {\t\t\n        var command = new AsyncReactiveCommand();\t\t\n\t\t\n        command.Subscribe(_ =\u003e\t\t\n        {\t\t\n            // heavy, heavy, heavy method....\t\t\n            return Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable();\t\t\n        });\t\t\n\t\t\n        // after clicked, button shows disable for 3 seconds\t\t\n        command.BindTo(button);\t\t\n\t\t\n        // Note:shortcut extension, bind aync onclick directly\t\t\n        button.BindToOnClick(_ =\u003e\t\t\n        {\t\t\n            return Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable();\t\t\n        });\t\t\n    }\t\t\n}\t\t\n```\n\n`AsyncReactiveCommand` has three constructor.\n\n* `()` - CanExecute is changed to false until async execution finished\n* `(IObservable\u003cbool\u003e canExecuteSource)` - Mixed with empty, CanExecute becomes true when canExecuteSource send to true and does not executing \n* `(IReactiveProperty\u003cbool\u003e sharedCanExecute)` - share execution status between multiple AsyncReactiveCommands, if one AsyncReactiveCommand is executing, other AsyncReactiveCommands(with same sharedCanExecute property) becomes CanExecute false until async execution finished\n\n```csharp\npublic class Presenter : MonoBehaviour\n{\n    public UnityEngine.UI.Button button1;\n    public UnityEngine.UI.Button button2;\n\n    void Start()\n    {\n        // share canExecute status.\n        // when clicked button1, button1 and button2 was disabled for 3 seconds.\n\n        var sharedCanExecute = new ReactiveProperty\u003cbool\u003e();\n\n        button1.BindToOnClick(sharedCanExecute, _ =\u003e\n        {\n            return Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable();\n        });\n\n        button2.BindToOnClick(sharedCanExecute, _ =\u003e\n        {\n            return Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable();\n        });\n    }\n}\n```\n\nMessageBroker, AsyncMessageBroker\n---\nMessageBroker is Rx based in-memory pubsub system filtered by type.\n\n```csharp\npublic class TestArgs\n{\n    public int Value { get; set; }\n}\n\n---\n\n// Subscribe message on global-scope.\nMessageBroker.Default.Receive\u003cTestArgs\u003e().Subscribe(x =\u003e UnityEngine.Debug.Log(x));\n\n// Publish message\nMessageBroker.Default.Publish(new TestArgs { Value = 1000 });\n```\n\nAsyncMessageBroker is variation of MessageBroker, can await Publish call.\n\n```csharp\nAsyncMessageBroker.Default.Subscribe\u003cTestArgs\u003e(x =\u003e\n{\n    // show after 3 seconds.\n    return Observable.Timer(TimeSpan.FromSeconds(3))\n        .ForEachAsync(_ =\u003e\n        {\n            UnityEngine.Debug.Log(x);\n        });\n});\n\nAsyncMessageBroker.Default.PublishAsync(new TestArgs { Value = 3000 })\n    .Subscribe(_ =\u003e\n    {\n        UnityEngine.Debug.Log(\"called all subscriber completed\");\n    });\n```\n\nUniRx.Toolkit\n---\n`UniRx.Toolkit` includes serveral Rx-ish tools. Currently includes `ObjectPool` and `AsyncObjectPool`.  It can `Rent`, `Return` and `PreloadAsync` for fill pool before rent operation.\n\n```csharp\n// sample class\npublic class Foobar : MonoBehaviour\n{\n    public IObservable\u003cUnit\u003e ActionAsync()\n    {\n        // heavy, heavy, action...\n        return Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable();\n    }\n}\n\npublic class FoobarPool : ObjectPool\u003cFoobar\u003e\n{\n    readonly Foobar prefab;\n    readonly Transform hierarchyParent;\n\n    public FoobarPool(Foobar prefab, Transform hierarchyParent)\n    {\n        this.prefab = prefab;\n        this.hierarchyParent = hierarchyParent;\n    }\n\n    protected override Foobar CreateInstance()\n    {\n        var foobar = GameObject.Instantiate\u003cFoobar\u003e(prefab);\n        foobar.transform.SetParent(hierarchyParent);\n\n        return foobar;\n    }\n\n    // You can overload OnBeforeRent, OnBeforeReturn, OnClear for customize action.\n    // In default, OnBeforeRent = SetActive(true), OnBeforeReturn = SetActive(false)\n\n    // protected override void OnBeforeRent(Foobar instance)\n    // protected override void OnBeforeReturn(Foobar instance)\n    // protected override void OnClear(Foobar instance)\n}\n\npublic class Presenter : MonoBehaviour\n{\n    FoobarPool pool = null;\n\n    public Foobar prefab;\n    public Button rentButton;\n\n    void Start()\n    {\n        pool = new FoobarPool(prefab, this.transform);\n\n        rentButton.OnClickAsObservable().Subscribe(_ =\u003e\n        {\n            var foobar = pool.Rent();\n            foobar.ActionAsync().Subscribe(__ =\u003e\n            {\n                // if action completed, return to pool\n                pool.Return(foobar);\n            });\n        });\n    }\n}\n```\n\nVisual Studio Analyzer\n---\nFor Visual Studio 2015 users, a custom analyzer, UniRxAnalyzer, is provided. It can, for example, detect when streams aren't subscribed to.\n\n![](StoreDocument/AnalyzerReference.jpg)\n\n![](StoreDocument/VSAnalyzer.jpg)\n\n`ObservableWWW` doesn't fire until it's subscribed to, so the analyzer warns about incorrect usage. It can be downloaded from NuGet.\n\n* Install-Package [UniRxAnalyzer](http://www.nuget.org/packages/UniRxAnalyzer)\n\nPlease submit new analyzer ideas on GitHub Issues!\n\nSamples\n---\nSee [UniRx/Examples](https://github.com/neuecc/UniRx/tree/master/Assets/Plugins/UniRx/Examples)  \n\nThe samples demonstrate how to do resource management (Sample09_EventHandling), what is the MainThreadDispatcher, among other things.\n\nWindows Store/Phone App (NETFX_CORE)\n---\nSome interfaces, such as  `UniRx.IObservable\u003cT\u003e` and `System.IObservable\u003cT\u003e`, cause conflicts when submitting to the Windows Store App.\nTherefore, when using NETFX_CORE, please refrain from using such constructs as `UniRx.IObservable\u003cT\u003e` and refer to the UniRx components by their short name, without adding the namespace. This solves the conflicts.\n\nDLL Separation\n---\nIf you want to pre-build UniRx, you can build own dll. clone project and open `UniRx.sln`, you can see `UniRx`, it is fullset separated project of UniRx. You should define compile symbol like  `UNITY;UNITY_5_4_OR_NEWER;UNITY_5_4_0;UNITY_5_4;UNITY_5;` + `UNITY_EDITOR`, `UNITY_IPHONE` or other platform symbol. We can not provides pre-build binary to release page, asset store because compile symbol is different each other.\n\nUPM Package\n---\nAfter Unity 2019.3.4f1, Unity 2020.1a21, that support path query parameter of git package. You can add `https://github.com/neuecc/UniRx.git?path=Assets/Plugins/UniRx/Scripts` to Package Manager\n\nor add `\"com.neuecc.unirx\": \"https://github.com/neuecc/UniRx.git?path=Assets/Plugins/UniRx/Scripts\"` to `Packages/manifest.json`.\n\nReference\n---\n* [UniRx/wiki](https://github.com/neuecc/UniRx/wiki)\n\nUniRx API documents.\n\n* [ReactiveX](http://reactivex.io/)\n\nThe home of ReactiveX. [Introduction](http://reactivex.io/intro.html), [All operators](http://reactivex.io/documentation/operators.html) are illustrated with graphical marble diagrams, there makes easy to understand. And UniRx is official [ReactiveX Languages](http://reactivex.io/languages.html).\n\n* [Introduction to Rx](http://introtorx.com/)\n\nA great online tutorial and eBook.\n\n* [Beginner's Guide to the Reactive Extensions](http://msdn.microsoft.com/en-us/data/gg577611)\n\nMany videos, slides and documents for Rx.NET.\n\n* [The future of programming technology in Unity - UniRx -(JPN)](http://www.slideshare.net/torisoup/unity-unirx) \n  - [Korean translation](http://www.slideshare.net/agebreak/160402-unirx)\n\nIntro slide by [@torisoup](https://github.com/torisoup)\n\n* [Reactive Programming, ​Unity 3D and you](http://slides.com/sammegidov/unirx#/)\n  - [Repository of UniRxSimpleGame](https://github.com/Xerios/UniRxSimpleGame)\n\nIntro slide and sample game by [@Xerios](https://github.com/Xerios)\n\n* [GDC 2016 Sessions of Adventure Capialist](https://www.youtube.com/watch?v=j3YhG91mPsU\u0026feature=youtu.be\u0026t=9m12s)\n\nHow to integrate with PlayFab API\n\nHelp \u0026 Contribute\n---\nSupport thread on the Unity forum. Ask me any question - [http://forum.unity3d.com/threads/248535-UniRx-Reactive-Extensions-for-Unity](http://forum.unity3d.com/threads/248535-UniRx-Reactive-Extensions-for-Unity)  \n\nWe welcome any contributions, be they bug reports, requests or pull request.  \nPlease consult and submit your reports or requests on GitHub issues.  \nSource code is available in `Assets/Plugins/UniRx/Scripts`.  \n\nAuthor's other Unity + LINQ Assets\n---\n[LINQ to GameObject](https://github.com/neuecc/LINQ-to-GameObject-for-Unity/) is a group of GameObject extensions for Unity that allows traversing the hierarchy and appending GameObject to it like LINQ to XML. It's free and opensource on GitHub.\n\n![](https://raw.githubusercontent.com/neuecc/LINQ-to-GameObject-for-Unity/master/Images/axis.jpg)\n\nAuthor Info\n---\nYoshifumi Kawai(a.k.a. neuecc) is a software developer in Japan.  \nCurrently founded consulting company [New World, Inc.](http://new-world.co/)  \nHe is awarding Microsoft MVP for Visual C# since 2011.  \n\nBlog: https://medium.com/@neuecc (English)  \nBlog: http://neue.cc/ (Japanese)   \nTwitter: https://twitter.com/neuecc (Japanese)\n\nLicense\n---\nThis library is under the MIT License.\n\nSome code is borrowed from [Rx.NET](https://github.com/dotnet/reactive/) and [mono/mcs](https://github.com/mono/mono).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneuecc%2Funirx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneuecc%2Funirx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneuecc%2Funirx/lists"}