Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

UniRx - Reactive Extensions for Unity

Discussion in 'Assets and Asset Store' started by neuecc, May 28, 2014.

  1. neuecc

    neuecc

    Joined:
    Apr 20, 2014
    Posts:
    108
    Thank you and sorry for late responses...
    I've very busied(for release new game and talk on Unite 2017 tokyo)

    https://www.slideshare.net/UnityTechnologiesJapan/unite-2017-tokyocunirx
    (Session slide at Unite 2017 Tokyo / in Japanese)

    But all of them have been completed.
    I'll start to work improve UniRx again.

    Curretnly not supported/tested on Unity 2017.
    I should check it quickly.
    Wait for a moment.

    Now, async/await supports requires `ENABLE_MONO_BLEEDING_EDGE_STANDALONE` define.
    Maybe its define removed on Unity 2017.
    If you add own ENABLE_MONO_BLEEDING_EDGE_STANDALONE define, maybe works.
     
  2. Astarorr

    Astarorr

    Joined:
    Jan 17, 2013
    Posts:
    41
    LTK likes this.
  3. slimshader

    slimshader

    Joined:
    Jun 11, 2013
    Posts:
    138
    RxMotion... interesting... (didn't get anything else tho :p)
     
  4. r1

    r1

    Joined:
    May 24, 2013
    Posts:
    2
    Hi. Often (but not always) I want my observer to trigger when it subscribes to a reactive property. To initialise a view or something.

    Is there a way to only have the observer triggered when it subscribes?

    For example:

    Code (CSharp):
    1. myProp
    2.     .Select( v => v == b )
    3.     .NextOnSubscribe()
    4.     .Subscribe( v => { Debug.Log(v) } ) // Called before changes to myProp
    5.  
    I've one solution which isn't great:

    Code (CSharp):
    1. public static class ObservableExtension {
    2.  
    3.     public static IObservable<T> NextOnSubscribe<T>(this IObservable<T> source ) {
    4.         var prop = source.ToReactiveProperty();
    5.         prop.DoOnSubscribe( () => { prop.Value = prop.Value; } );
    6.         return prop;
    7.     }
    8. }
    as it will also update previous subscribers too.

    Any advise appreciated? Perhaps it's a case of making a new observer? Thanks
     
  5. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    609
    If it's a normal reactive property (not constructed from another IObservable<T> source) it should provide the current value on subscribe. Otherwise, the Value property setter needs to have been called before this behavior will happen. If HasValue is true, this should work, and also if HasValue is true, you can read the current Value from the property before you make the subscription (this is what I do in my current codebase).

    You can look at the code in the UniRx solution for ReactiveProperty.cs to get a better idea of how it all works internally.
     
    r1 likes this.
  6. hornetfire

    hornetfire

    Joined:
    Mar 24, 2017
    Posts:
    4
  7. slimshader

    slimshader

    Joined:
    Jun 11, 2013
    Posts:
    138
    Hi,

    is there a way to make 2-way binding of ReactiveProperties to UI controls? For example I'd like to have ReactiveProperty<bool> bound to a Toggle in such way that setting a Value of that RP would also be reflected in Toggle state, similarly for InputField and ReactiveProperty<string> (assigning to Value or RP is reflected in UI element).

    Currently it only seems to work 1-way, from UI -> RP but not the other way around. Setting them up like this:

    Code (CSharp):
    1.     StringEdit = xmlLayout.GetElementById<InputField>("nameEdit")
    2.       .OnValueChangedAsObservable()
    3.       .ToReactiveProperty();
    4.  
    5.     Toggle = xmlLayout.GetElementById<Toggle>("toggle")
    6.       .OnValueChangedAsObservable()
    7.       .ToReactiveProperty();
    8.  
     
  8. slimshader

    slimshader

    Joined:
    Jun 11, 2013
    Posts:
    138
    It should report initial value on Subscribe automatically, maybe you forgot to 'new' it before Subscribing to it?
     
  9. zeroonline

    zeroonline

    Joined:
    Mar 16, 2014
    Posts:
    1
    Hi. I need to load a bunch of files in parallel. I'm trying to do this, as in the example:

    Code (CSharp):
    1.   var loadingList = new List<IObservable<WWW>>();
    2.  
    3. foreach (var keyValuePair in loadedData)
    4. {
    5.     var xmlPath = _configsPath + keyValuePair.Key + ".xml";
    6.     loadingList.Add(ObservableWWW.GetWWW(xmlPath));
    7. }
    8.  
    9. loadingList.WhenAll().Subscribe(wwws =>
    10. {
    11.     Debug.Log(wwws);
    12. });
    But when a callback invoking, the www classes are already destroyed. What am I doing wrong?
     
  10. elasto

    elasto

    Joined:
    Mar 20, 2014
    Posts:
    18
    Apologies if this has been asked previously, but what is the garbage generation like when using this asset? Is it the same as using native Unity?
     
  11. LTK

    LTK

    Joined:
    Jul 16, 2015
    Posts:
    24
    I agree with you :D
     
  12. Wolar

    Wolar

    Joined:
    Sep 25, 2014
    Posts:
    31
    Hello, first of all thanks for a great library. I have a question, I'm just getting into Reactive Programming (native iOS and Unity) and one thing always confuses me. If "everything is a stream" what is a proper way of storing (save & load) game state? I can imagine having game state in ReactiveProperties which can be seriallized and also can be observed for changes. But I don't feel like this is the right Rx way. Another thing that comes to my mind is pull out the last item from every observable I care about during the save and during the load, initialize the streams with this saved value, but that sounds a little bit shaky and like a lot of extra work.
     
  13. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    655
    So there seems to be at least a chunk of UniRx that is .NET 4.5 code ported into Unity. However with the newer version of Unity allowing native support for .NET 4.5, this code is causing collision.

    Is there any one given spot where I can find this code and remove it, or is it scattered throughout the library?
     
  14. dotmos

    dotmos

    Joined:
    Jan 2, 2011
    Posts:
    26
    We are using UniRX in combination with Unity for some years now and are REALLY happy with it.
    During the last 2 months we are getting strange errors though, which are really hard to fix, as the callstack is not very helpful.

    For example there might be a null reference error somewhere. But the console does not tell us where, but always points to Observer.cs.
    Or there might be an IEnumeration that is being changed during a foreach loop of that same IEnumarion. Again, we don't know where this happens, as we are only pointed to Observer.cs.
    Fixing bugs became really tedious and a lot of guessing work.

    We then thought that maybe something is wrong with our thread management, so we removed that and put everything back on the main thread for testing. Still, same error. We then removed all MicroCoroutines. Same error.

    Here is the callstack for a random error so you can see what the problem is:

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2.  
    3. UniRx.Stubs.<Throw>m__1 (System.Exception ex) (at Assets/GameFramework/Modules/UniRx/Scripts/Observer.cs:495)
    4.  
    5. UniRx.Observer+Subscribe`1[T].OnError (System.Exception error) (at Assets/GameFramework/Modules/UniRx/Scripts/Observer.cs:172)
    6.  
    7. UniRx.Operators.FromMicroCoroutineObservable`1+FromMicroCoroutine[T].OnError (System.Exception error) (at Assets/GameFramework/Modules/UniRx/Scripts/UnityEngineBridge/Operators/FromCoroutine.cs:130)
    8.  
    9. UniRx.ObserveExtensions+<PublishUnityObjectValueChanged>c__Iterator2`2[TSource,TProperty].MoveNext () (at Assets/GameFramework/Modules/UniRx/Scripts/UnityEngineBridge/ObserveExtensions.cs:233)
    10.  
    11. UniRx.InternalUtil.MicroCoroutine.Run () (at Assets/GameFramework/Modules/UniRx/Scripts/InternalUtil/MicroCoroutine.cs:70)
    12.  
    13. UnityEngine.Debug:LogException(Exception)
    14.  
    15. UniRx.MainThreadDispatcher:<unhandledExceptionCallback>m__3(Exception) (at Assets/GameFramework/Modules/UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs:389)
    16.  
    17. UniRx.MainThreadDispatcher:<Awake>m__0(Exception) (at Assets/GameFramework/Modules/UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs:492)
    18.  
    19. UniRx.InternalUtil.MicroCoroutine:Run() (at Assets/GameFramework/Modules/UniRx/Scripts/InternalUtil/MicroCoroutine.cs:92)
    20.  
    21. UniRx.<RunUpdateMicroCoroutine>c__Iterator0:MoveNext() (at Assets/GameFramework/Modules/UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs:530)
    22.  
    23. UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
    The "NullReferenceException: Object reference not set to an instance of an object" really is only an example here. This could be anything.
    The error always begins with Observer.cs and ends in MainThreadDispatcher.cs. There is never any traceable route to an error in our code. But in the end it always is an error in our code and each time we have to guess were it comes from.

    We are on Unity 2017.1.1p1 with NET 4.6 and use the latest version of UniRx.

    Any ideas what is going on here?
     
  15. dotmos

    dotmos

    Joined:
    Jan 2, 2011
    Posts:
    26
    Just writing about things sometimes helps: I added a dirty "fix" to Observer.cs so we can get better feedback from our testers.

    In class Stubs in Observer.cs add
    Code (CSharp):
    1. UnityEngine.Debug.LogError("Custom error for Observer.cs : \n"+ex.StackTrace);
    to

    Code (CSharp):
    1. public static readonly Action<Exception> Throw = ex => {
    2.            throw ex;
    3. };
    so it becomes

    Code (CSharp):
    1. public static readonly Action<Exception> Throw = ex => {
    2.            UnityEngine.Debug.LogError("Custom error for Observer.cs : \n"+ex.StackTrace);
    3.            throw ex;
    4.        };
    Not very nice, but it does the job.
     
  16. slimshader

    slimshader

    Joined:
    Jun 11, 2013
    Posts:
    138
    Hey, latest release (5.5.0) is not compatible with Unity 2017 due to duplicated IObservable etc. I see commits on Github related to that issue but no update on Asset Store, is it coming?
     
    tomerpeledNG and fakegood like this.
  17. YoungXi

    YoungXi

    Joined:
    Jun 5, 2013
    Posts:
    49
    Hello, first of all, thanks for what you've done.

    And, I was wondering do you need to clear the Observable and how do you do that?

    I'm now not using UniRx, but planning to. So, in my case, some of the UI elements are cached in pools

    From what I know, I should remove those listeners(observables) before recycle them into the pool:
    e.g.
    If I have a button.onClick registered via
    button.onClick.AddListener();
    , then I have to do
    button.onClick.RemoveAllListeners();
    before it ends up in the pool, so that next I get it back from the pool, I can add brand new listeners to it.
     
  18. tomerpeledNG

    tomerpeledNG

    Joined:
    Jul 14, 2017
    Posts:
    81
    Hi,

    We want to start to use this wonderful library, was wondering if we should work with the updated GitHub code or with the asset store version?
     
  19. Crazydadz

    Crazydadz

    Joined:
    Mar 29, 2012
    Posts:
    50
    @tomerpeled You should use the updated GitHub code. The asset store version is not up to date.
     
  20. vs-cby

    vs-cby

    Joined:
    Jun 23, 2017
    Posts:
    5
    Hi folks,
    We are adopting UniRx now in our Unity application. Seems powerful, congratulations!
    My question,
    how can I achieve the following with UniRx observables:
    I have a long-lasting operation that blocks the main thread. I need to notify some other class about the progress, but on a time based scale, say every second.
    I found that Observable.Interval does not emit during the operation, and only resumes after it's done.
    How to resolve this? I feel there is something obvious that I don't see.
    Thanks a lot in advance.
     
  21. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    609
    There's an interface that can be used used with the ObservableWWW family of functions that I've co-opted for this very thing before, IProgress<T>. It has a Report(T value) function, and you can write your own thread safe implementation and pass it along to your worker logic, updating as needed.
     
  22. tomerpeledNG

    tomerpeledNG

    Joined:
    Jul 14, 2017
    Posts:
    81
    What is the best approach to handle errors when using the AsyncMessageBroker?

    I'm trying to catch such errors from other Observable, with no success:


    Code (CSharp):
    1.  Observable.Start(async () =>
    2.             {
    3.                 await AsyncMessageBroker.Default.PublishAsync(new SomeEvent());
    4.             }, Scheduler.ThreadPool)
    5.             .DoOnError(ex =>
    6.             {
    7.                 _logger.Error($"Error firing...", ex);
    8.             })
    9.             .Subscribe();
    If one of the subscribers for SomeEvent throws exception, it won't get to the DoOnError from above.
    How should I handle such scenarios? Try/catch on each PublishAsync???
     
  23. asukiaaa

    asukiaaa

    Joined:
    Aug 5, 2016
    Posts:
    2
    I asked as issue on github but please allow me to ask my problem even on this thread.

    I got error when I try to call UniRx for UWP app from cli.
    If I execute some method in some class by cli like this
    Code (csharp):
    1. "C:\Program Files\Unity2017.2.1p2\Editor\Unity.exe" -batchmode -quit -logFile build.log -projectPath "C:\Users\who-am-i\my-unity-prject" -executeMethod Builderr.CliBuildWindows
    it leaves these errors on the log file.
    Code (csharp):
    1. Assets/Plugins/UniRx/Scripts/Observable.Awaiter.cs(8,24): error CS0234: The type or namespace name `Tasks' does not exist in the namespace `System.Threading'. Are you missing an assembly reference?
    2.  
    3. Assets/Plugins/UniRx/Scripts/Tasks/TaskObservableExtensions.cs(6,24): error CS0234: The type or namespace name `Tasks' does not exist in the namespace `System.Threading'. Are you missing an assembly reference?
    4.  
    5. Assets/Plugins/UniRx/Scripts/UnityEngineBridge/CoroutineAsyncBridge.cs(9,24): error CS0234: The type or namespace name `Tasks' does not exist in the namespace `System.Threading'. Are you missing an assembly reference?
    6.  
    7. Assets/Plugins/UniRx/Scripts/UnityEngineBridge/UniRxSynchronizationContext.cs(8,24): error CS0234: The type or namespace name `Tasks' does not exist in the namespace `System.Threading'. Are you missing an assembly reference?
    8.  
    9. Assets/Plugins/UniRx/Scripts/InternalUtil/ListObserver.cs(7,36): error CS0305: Using the generic type `UniRx.IObserver<TValue,TResult>' requires `2' type argument(s)
    10.  
    11. Assets/Plugins/UniRx/Scripts/Notification.cs(29,22): (Location of the symbol related to previous error)
    12.  
    13. Assets/Plugins/UniRx/Scripts/InternalUtil/ListObserver.cs(65,37): error CS0305: Using the generic type `UniRx.IObserver<TValue,TResult>' requires `2' type argument(s)
    14.  
    15. ...
    Code (csharp):
    1. Unhandled Exception:
    2.  
    3. Mono.CSharp.InternalErrorException: Assets/Plugins/UniRx/Scripts/Operators/Merge.cs(4,17): UniRx.Operators ---> Mono.CSharp.InternalErrorException: Assets/Plugins/UniRx/Scripts/Operators/Merge.cs(6,20): UniRx.Operators.MergeObservable<T> ---> Mono.CSharp.InternalErrorException: Assets/Plugins/UniRx/Scripts/Operators/Merge.cs(36,15): UniRx.Operators.MergeObservable<T>.MergeOuterObserver ---> System.ArgumentException: An item with the same key has already been added.
    4.  
    5.   at System.ThrowHelper.ThrowArgumentException (System.ExceptionResource resource) [0x0000b] in <9c9f068c46c64ffd91fda7af157b4d15>:0
    6.  
    7.   at System.Collections.Generic.Dictionary`2[TKey,TValue].Insert (TKey key, TValue value, System.Boolean add) [0x0007c] in <9c9f068c46c64ffd91fda7af157b4d15>:0
    8.  
    9.   at System.Collections.Generic.Dictionary`2[TKey,TValue].Add (TKey key, TValue value) [0x00000] in <9c9f068c46c64ffd91fda7af157b4d15>:0
    10.  
    11. ...
    Code (csharp):
    1. - Finished compile Library/ScriptAssemblies/Assembly-CSharp-firstpass.dll
    2.  
    3. Assets/Plugins/UniRx/Scripts/Observable.Awaiter.cs(8,24): error CS0234: The type or namespace name `Tasks' does not exist in the namespace `System.Threading'. Are you missing an assembly reference?
    4.  
    5. (Filename: Assets/Plugins/UniRx/Scripts/Observable.Awaiter.cs Line: 8)
    6.  
    7. Assets/Plugins/UniRx/Scripts/Tasks/TaskObservableExtensions.cs(6,24): error CS0234: The type or namespace name `Tasks' does not exist in the namespace `System.Threading'. Are you missing an assembly reference?
    8.  
    9. (Filename: Assets/Plugins/UniRx/Scripts/Tasks/TaskObservableExtensions.cs Line: 6)
    10.  
    11. ...
    The error does not occurre when I select Standalone as platform.

    My environment

    | name | version |
    | ------------- | ------------- |
    | OS | Windows 10 Pro |
    | Unity | 2017.2.1p2 |
    | Unity Player Runtime Version | Stable (.Net 3.5) |
    | Unity Api Compatibility Level | .Net 4.6 |

    Is there any way to resolve this problem?

    Thank you.
     
    Last edited: Feb 15, 2018
  24. boysenberry

    boysenberry

    Joined:
    Jul 28, 2014
    Posts:
    341
    Hi there,

    First, thank you for UniRx, super useful and awesome!

    I've noticed some 'oddness' while implementing OnValueChangedAsObservable() vs onValueChanged.AsObservable() while handling UGUI slider updates.
    While using OnValueChangedAsObservable() it runs my lambada expression on assignment vs onValueChanged.AsObservable() while only runs with a value change.

    Is that a known behavior? Should I expect that while using OnValueChangedAsObservable()? What is the main difference between the two versions?

    Thanks in advance,
    Boysenberry
     
  25. asukiaaa

    asukiaaa

    Joined:
    Aug 5, 2016
    Posts:
    2
    My team member avoided the errors with using master branch source on github.
    https://github.com/neuecc/UniRx

    Thank you.
     
  26. VegaStudio_Kevin

    VegaStudio_Kevin

    Joined:
    Jun 11, 2014
    Posts:
    12
    Code (CSharp):
    1. class ArenaService : SystemServiceMonoBehavior
    2.     {
    3.         [Inject] public PlayerService pservice;
    4.         [Inject] public LeagueService gservice;
    5.        
    6.         public override void Setup()
    7.         {
    8.         }
    9.  
    10.         private void loadArena(Player player)
    11.         {          
    12.         }
    13.  
    14.         private void checkNewArena(Player player)
    15.         {  
    16.         }
    17.     }
    Code (CSharp):
    1.  gameObject.AddComponent(typeof(ArenaService));
    2.             GetComponent<ArenaService>().Setup();
    Hello, when i add this script at runtime to a component how can is inject that field automatic?
     
  27. Ethan_VisualVocal

    Ethan_VisualVocal

    Joined:
    Mar 23, 2016
    Posts:
    150
    The comment for that method says "Observe onValueChanged with current `value` on subscribe." so, it looks pretty intentional to me:
    https://github.com/neuecc/UniRx/blo...ngineBridge/UnityUIComponentExtensions.cs#L69
     
    boysenberry likes this.
  28. boysenberry

    boysenberry

    Joined:
    Jul 28, 2014
    Posts:
    341
    Yeah, once I realized the difference I just needed to file it away in the memory banks so I don't get unexpected behaviors. It reminds me of a do/while loop, vs a while loop in perl. Easy enough to compensate for. Thanks for the heads up on RTFMing, hehe, I should always start there.
     
    Ethan_VisualVocal likes this.
  29. Carol12

    Carol12

    Joined:
    Sep 9, 2017
    Posts:
    2
    hello ! i use UniRx pool instance monster, now i want to set different monster name by scritableObject name ,
    public ActorPooler(T aprefab,Transform aparent,EnemyCfg _cfg)
    {
    this.prefab = aprefab;
    if (aparent == null)
    {
    this.hierarchyParent = shareParent;
    }
    else
    {
    this.hierarchyParent = aparent;
    }
    this.cfg = _cfg;
    }
    protected override T CreateInstance()
    {
    var instance = GameObject.Instantiate<T>(prefab);
    if (cfg == null)
    {
    Debug.Log("?");
    }
    instance.name = cfg.name;
    instance.transform.SetParent(hierarchyParent);
    return instance;
    }

    i start play is show nullReference error and debug.log cfg is null . i set cfg in constructor why not is report null
     
  30. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    877
    Hello there,
    I have seen this asset being talked about before but am wondering if anyone might be able to rattle off some practical examples of what it could be used for? I see a lot of thing relating WWW and websites. Is this something that might be useful in an online RPG game? If so, what might it be used for? I am always looking to learn new things that can help make my game better.

    Thanks!
     
  31. boysenberry

    boysenberry

    Joined:
    Jul 28, 2014
    Posts:
    341
    One example I use it for is a cleaner way for handling events. There are a ton of event listener types for handling unity events. Reactive programming in general works really well when you need instant reactions to user or machine input. You can wire up how you want things to behave while avoiding a lot of boiler plate code and the like.
    Hope that helps. There is a ton of info about reactive programming online that will do a much better job than I at explaining though.
     
    MostHated likes this.
  32. bardic

    bardic

    Joined:
    Feb 8, 2012
    Posts:
    9
    Hey,
    Was wondering how I would go about using this to handle a PUT webrequest. I have Posts and Gets working but the API I need to consume is also using Puts.

    Thanks!
     
  33. Bendistocratic

    Bendistocratic

    Joined:
    Mar 7, 2015
    Posts:
    4
    Hi, I was wondering if there is a TakeUntilDisable() method just for scripts? Right now I would need to disable and re-enable the GameObject in order for the events to be unsubscribed.

    Is there any way I can simply unsubscribe an event from a script by disabling the script itself?

    Thank you!

    EDIT: The current way is to use CompositeDisposable
     
    Last edited: May 30, 2018
  34. Ethan_VisualVocal

    Ethan_VisualVocal

    Joined:
    Mar 23, 2016
    Posts:
    150
    A built in way? Not to my knowledge, no. The way "...UntilDisable()" and "AddTo(..)" work is they add another MonoBehavior to the parent GameObject which cleans things up when OnDisable is called on it.

    You could create a subclass of MonoBehavior that imitates this behavior and inherit from that, but I don't recommend this because of the complications and costs of making methods like OnDisable virtual.

    Another approach involves re-architecting your app to use less MonoBehaviors, and instead have one "Manager" MonoBehavior that handles events to/from children, but that's probably not what you want right now o_O (Link for topic: https://blogs.unity3d.com/2015/12/23/1k-update-calls/)

    I think the simplest option is having a CompositeDisposable, per MonoBehavior you want to be able to disable individually (as you mentioned.)
     
    Bendistocratic likes this.
  35. soxroxr

    soxroxr

    Joined:
    Jul 17, 2012
    Posts:
    60
    I'm wondering, does this still have use now with the job system and ECS? Is it better than those in some scenarios? Will it work in conjunction with them?
     
    NeatWolf likes this.
  36. Jos-Yule

    Jos-Yule

    Joined:
    Sep 17, 2012
    Posts:
    279
    @soxroxr I'm not sure that there is even a specific overlap between these two libraries? How do you see using the ECS in a situation that you are using UniRX? Or vice-versa?
     
  37. soxroxr

    soxroxr

    Joined:
    Jul 17, 2012
    Posts:
    60
    I don't fully understand what ReactiveX and UniRx are, I'm trying to figure that out. If they work well in tandem that's great - if there's no overlap I don't see why they wouldn't. I've read that there's much to be gained in usability, readability, and performance by going with UniRx, so I'd like to really understand it and maybe use it. That's why I wanted to ask - I'm going to start learning the ECS pattern now and I didn't want to spend time learning UniRx if they were going to clash. Just doing some recon.
     
  38. rjvromans

    rjvromans

    Joined:
    Oct 14, 2018
    Posts:
    5
    Hello all,

    I have a question regarding the AsyncReactiveCommand. See the class below

    public class TestBehaviour : MonoBehaviour
    {
    public Button m_loginButton;

    // Use this for initialization
    void Start()
    {
    // Below are 2 ways that subcribe to a AsyncReactiveCommand.
    // Both lines will disable / enable the button as expected.

    // 1) This line will, after the 3 seconds, automatically set the color of the button to back to light grey (enabled).
    DoLogin.Subscribe(_ => Observable.Timer(TimeSpan.FromSeconds(3)).AsUnitObservable());

    // 2) But this line will not automatically set the color of the button back to light gray after 3 seconds.
    // Instead It stays dark grey.
    //DoLogin.Subscribe(_ => AwaitTask().ToObservable());
    DoLogin.BindTo(m_loginButton);
    }

    public AsyncReactiveCommand DoLogin { get; } = new AsyncReactiveCommand();

    async Task AwaitTask()
    {
    await Task.Delay(3000);
    }
    }

    Anybody knows what is going on?

    Best regards,
    Ronald
     
    Last edited: Dec 2, 2018
  39. rjvromans

    rjvromans

    Joined:
    Oct 14, 2018
    Posts:
    5
    The above issue is resolved when I use UniTask instead of Task.

    Still I would like to know why the issue was present when using System.Threading.Tasks.Task.
     
    Last edited: Dec 2, 2018
  40. sinzer0

    sinzer0

    Joined:
    Aug 29, 2013
    Posts:
    143
    Just wanted to say I love the new Async library. Makes scripting over time so much easier. While unity is off building a monster (ECS) this one man dev from japan filled a major hole in Unity in a much more elegant way.

    Great Job!
     
    MaDDoX likes this.
  41. SLAS

    SLAS

    Joined:
    Aug 4, 2013
    Posts:
    13
    anyone know if this works with unity 2018.3?
     
  42. sinzer0

    sinzer0

    Joined:
    Aug 29, 2013
    Posts:
    143
    Yes it has since beta
     
  43. curiousAmit

    curiousAmit

    Joined:
    May 15, 2015
    Posts:
    8
    Help Needed:
    Is there any
    Code (CSharp):
    1. obs.ThrottleFirst(_=>observable)
    ?
    I want to have dynamic throttle time instead of constant.
     
  44. zhuMissYou

    zhuMissYou

    Joined:
    Jan 26, 2019
    Posts:
    2
    hello, i found a exception in use Observable.Start each stop play,so i try to change the follow codes ,then the exception not appear,but i am not sure it correct,please reply to my email zyf151@qq.com
    upload_2019-1-26_12-28-3.png upload_2019-1-26_12-21-59.png
     

    Attached Files:

    Last edited: Jan 26, 2019
  45. Ethan_VisualVocal

    Ethan_VisualVocal

    Joined:
    Mar 23, 2016
    Posts:
    150
    You should file an issue in the author's github repo:
    https://github.com/neuecc/UniRx
     
  46. zhuMissYou

    zhuMissYou

    Joined:
    Jan 26, 2019
    Posts:
    2
  47. Laguna_Seca

    Laguna_Seca

    Joined:
    Mar 13, 2014
    Posts:
    121
    Hello! I wanted to use UniRx for some complex operations. As I understand it, UniRx allows you to execute them asynchronously without freezing frames.

    Tell me if I'm doing it right:
    1. Activation of the object

    Code (CSharp):
    1.  
    2. car.ObserveEveryValueChanged(x => x.gameObject).ObserveOnMainThread().Subscribe(x => x.gameObject.SetActive(true));
    3.  
    Is it necessary to call Subscribe via ObserveOnMainThread? Do I activate the object correctly? Is it even possible to use unirx for these purposes?

    2. Reading and writing sqlite data

    Code (CSharp):
    1.  
    2. Observable.Start(GetGetTotalRoomsRevenueAsync).ObserveOnMainThread().Subscribe(x => totalRoomsRevenue = x);
    3.  
    GetGetTotalRoomsRevenueAsync:
    Code (CSharp):
    1.  
    2. int GetGetTotalRoomsRevenueAsync()
    3.         {
    4.            return DB.instance.GetTotalRoomsRevenue();
    5.         }
    6.  
    3. Data recording
    Code (CSharp):
    1.  
    2. Observable.Start(UpdateEconomyDataAsync).Subscribe();
    3.  
    UpdateEconomyDataAsync:
    Code (CSharp):
    1.  
    2. void UpdateEconomyDataAsync()
    3.         {
    4.             string newTimeStamp = DateTime.Now.ToString();
    5.             DB.instance.UpdateEconomyData(globalMoney, alcohol, tobacco, newTimeStamp);
    6.             previousTimeStamp = newTimeStamp;
    7.  
    8.         }
    9.  
     
  48. missli93

    missli93

    Joined:
    Oct 5, 2018
    Posts:
    3
    it's so cool . does it support on ps4 platform?
     
  49. s1m0n1stv4n

    s1m0n1stv4n

    Joined:
    Sep 14, 2012
    Posts:
    14
    Hi everyone,

    I've got a question about the MessageBroker. Let's say I've a class and a subclass of it, A and B. We also subscribe to these types, the following way:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. using UniRx;
    6.  
    7. public class Test : MonoBehaviour
    8. {
    9.  
    10.     void Start()
    11.     {
    12.  
    13.         MessageBroker.Default.Receive<A>().Subscribe(a =>
    14.         {
    15.             Debug.Log("subscribed to A, the type is " + a.GetType()); //outputs: subscribed to A, the type is B
    16.         });
    17.  
    18.         MessageBroker.Default.Receive<B>().Subscribe(b =>
    19.         {
    20.             Debug.Log("subscribed to B, the type is " + b.GetType()); //never triggers
    21.         });
    22.  
    23.  
    24.         var bb = new B();
    25.  
    26.         bb.SendItself();
    27.  
    28.     }
    29.  
    30. }
    31.  
    32.  
    33. public class A
    34. {
    35.     public void SendItself()
    36.     {
    37.         MessageBroker.Default.Publish(this);
    38.     }
    39. }
    40.  
    41. public class B : A
    42. {
    43.  
    44. }
    45.  

    So when I, try to Publish(this), from the subclass (and from an inherited method), the subscription to the subclass (B) never triggers. On the other hand, the subscription to the base class (A) triggers, although the type of the object seems to be the subclass at runtime!

    Can someone please explain why is this happening, and how to get around it?

    Thanks!
     
  50. jwvanderbeck

    jwvanderbeck

    Joined:
    Dec 4, 2014
    Posts:
    655
    I'm confused when trying to use UniTask.

    According to documentation on normal Task, you define a method return as Task<T> but return just T, EG:

    Code (CSharp):
    1. public Task<string> MyFunc()
    2. {
    3.     return "foo"
    4. }
    Looking at the sparse documentaion on UniRx's UniTask, it shows the say thing:

    Code (CSharp):
    1. public UniTask<string> MyFuncUni()
    2. {
    3.     return "foo"
    4. }
    However this doesn't seem to be working for me, as I just get an error:
    Cannot convert expression type "string" to return type "UniRx.Async.UniTask<string>"