Update UniRx 5.4.1 and LINQ to GameObject 2.2

I’ve updated two Unity libraries, and today, they were accepted on Unity AssetStore. Please check and update! I will introduce what’s new and some details.

UniRx 5.4.1

UniRx 5.4.1, this update is a small release. The main feature is to support Unity 5.5 Beta. Last week, Unity 5.5 beta was released. It is excellent (especially C# compiler upgrade!), but unfortunately, Unity’s auto script upgrade program brakes UniRx, so it can’t compile. Why?

Unity 5.5 deprecates MonoBehaviour.StartCoroutine_Auto, use StartCoroutine instead and upgrade program automatically, convert to StartCoroutine. Okay, it almost works, but UniRx does not because UniRx defines

new public static Coroutine StartCoroutine(IEnumerator coroutine)

If it calls StartCoroutine from the inner method, the compiler is confused. Is it static method? Is it instance base MonoBehaviour method? I’ve fixed it by rewriting, explicitly calling base MonoBehaviour.StartCoroutine.

Release Notes

Improvement: Support Unity 5.5 Beta
Fix: ThrottleFirstFrame throws NullReferenceException when stream sends OnNext immediately. #160, thanks @hsanno
Fix: Error on LogEntry.cs #164, thanks @kimsama
Fix: ToReadOnlyReactiveProperty should be distinct publishing #161
Fix: To(ReadOnly)ReactiveProperty cause strange result when source observable returns OnCompleted or OnError
(Breaking) Changes: PresenterBase was obsoleted(but it only commented, not marked [Obsolete])
Breaking Changes: Sample14 was removed
Breaking Changes: Removed ObservableMonoBehaviour, TypedMonoBehaviour in UNITY 5.5 or newer

Sorry, PresenterBase is obsolete because PresenterBase is too complex and lost stack trace, so it has low debuggability. You should define a simple Initialize method and call from parent to child; it works for most scenarios.

LINQ to GameObject 2.2

LINQ to GameObject is GameObject extensions for Unity that allow a traverse hierarchy and append GameObject. The design aims both to get the power of LINQ and the performance of iteration.

Image for post

So yes, performance! I sometimes hear, “LINQ is slow. Do not use LINQ as it causes heavy allocations.” Hmn, it is true that LINQ causes heavy allocations.

In Unity, “LINQ” means LINQ to Objects. Select().Where()..., it create Enumerable objects on a number of method chains. There allocate Enumerator objects when called GetEnumerator. If used in lambda and capture variable, create a hidden class by the compiler; this is allocation.

In UniRx? Select().Where()…, it create Observable objects on a number of method chains. There allocate IDisposable objects when called Subscribe. If used in lambda and capture variable, create a hidden class by the compiler; this is allocation.

It is the same. But the difference is the sequence lifetime. I avoid using LINQ to Objects on a tight loop (for example, Update). UniRx (Reactive Pattern) mainly creates and subscribes only once and runs for a long time. If it runs in the pipeline, it does not allocate more (if you use the simple method).

In LINQ to GameObject? LINQ to GameObject’s traverse method does not allocate GC memory because it uses a hand-optimized struct enumerator. The unity compiler has bugs, so the struct enumerator(such as foreach List<T>) causes boxing and allocates GC memory, but Unity 5.5 and 5.3, 5.4’s compiler upgrade patch, can avoid it!

Some chain methods pass through the optimized path, for example, First, FirstOrDefault, ToArray, ForEach and ToArrayNonAlloc.

Release Notes

Add: Descendants/DescendantsSelf(descendIntoChildren) overload
Add: IEnumerable.Destroy(detachParent) overload
Performance Optimize: Children().ToArray() by use fixed array
Performance Optimize: Children().Destroy(detachParent) by use transform.DetachChildren

Descendants(descendIntoChildren) is borrowed from Roslyn, it stops traverse children when does not match condition.

Written by

a.k.a. neuecc. Creator of UniRx, UniTask, MessagePack for C#, MagicOnion etc. Microsoft MVP for C#. CEO/CTO of Cysharp Inc. Live and work in Tokyo, Japan.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store