Esempio n. 1
0
        // Start is called before the first frame update
        protected override void Start()
        {
            m_CategoryPagerView.items.Value = m_Categories;

            var categoryObservable = category as IObservable <CategoryEnum>;
            var isDragAndDropping  = new BoolReactiveProperty(false);

            // If we have at least one category, start with it
            if (m_Categories.Length > 0)
            {
                categoryObservable = categoryObservable.StartWith(m_Categories[0].category);
            }

            // Change the catalogue pager whenever the category button is pressed or the color changes.
            Observable.Merge(
                categoryObservable
                .DistinctUntilChanged()
                .AsUnitObservable(),
                flipped.DistinctUntilChanged()
                .AsUnitObservable(),
                color.DistinctUntilChanged()
                .AsUnitObservable()
                )
            .Subscribe(ignored =>
            {
                var catalogueItems = m_Asset[category.Value, color.Value]
                                     .Select(item => new CatalogueItem()
                {
                    flipped = flipped.Value,
                    asset   = item
                })
                                     .ToArray();

                m_CataloguePagerView.items.Value = catalogueItems;

                if (m_Brush.Value != null)
                {
                    var index = Array.FindIndex(catalogueItems,
                                                item => item.asset.name == m_Brush.Value.catalogueItem.asset.name);

                    if (index >= 0)
                    {
                        // If the color or flip state changed, it now changed here
                        var brush = new BrushItem()
                        {
                            catalogueItem = catalogueItems[index]
                        };
                        m_Brush.SetValueAndForceNotify(brush);
                    }
                }

                var hit = new EventHitBuilder()
                          .SetEventCategory("profile creator")
                          .SetEventAction("brush")
                          .SetEventLabel($"category={category.Value}, color={color.Value}, flipped={flipped.Value}")
                          .SetEventValue(drawingView.stampItems.Count);
                GoogleAnalyticsV4.getInstance().LogEvent(hit);
            })
            .AddTo(this);

            category.Value = m_Categories[0].category;

            // Whenever we click on a catalogue item, set that image as the current brush, then stamp its pixels onto
            // the drawing image with our brush when it is clicked
            m_CataloguePagerView.OnCatalogueItemPointerClickAsObservable()
            .Subscribe(tuple =>
            {
                // If we clicked instead of dragged the item, we're definitely not dragging
                isDragAndDropping.Value = false;
                brush.Value             = new BrushItem()
                {
                    catalogueItem = tuple.Item2
                };
            })
            .AddTo(this);

            // If we switch into the screen view that contains the editing profile text, copy in the image to it
            m_UiScreenView.onScreenBeginTransition.AsObservable()
            .Where(targetScreen => targetScreen == m_EditingProfileTextScreen.screenIndex)
            .Subscribe(ignored => { Drawing.PostDrawing(drawingView, m_EditingProfileTextDrawingView); })
            .AddTo(this);

            // Drawing code
            var opaque      = new Color(1f, 1f, 1f, 1f);
            var transparent = new Color(1f, 1f, 1f, m_PreviewBrushTransparency);

            // Draw a preview of the brush
            var previewBrush = new GameObject("Preview Brush");
            var previewImage = previewBrush.AddComponent <Image>();

            // The preview image brush naturally should not receive raycasts / should not block
            previewImage.raycastTarget = false;
            var previewBrushTransform = previewBrush.transform as RectTransform;

            Debug.Assert(previewBrushTransform != null, nameof(previewBrushTransform) + " != null");

            // Changes the preview's sprite as long as the brush is not null. The brush is actually set inactive later.
            // Also reacts to when the flipping setting changes.
            brush
            .Where(b => brush.Value != null && brush.Value.sprite != null)
            .Subscribe(b =>
            {
                previewImage.sprite = b.sprite;
                previewImage.rectTransform.localScale =
                    new Vector3(b.flipped ? -1.0f : 1f, 1f, 1f);
                previewImage.SetNativeSize();
            })
            .AddTo(this);

            // Move the preview brush along with the mouse as long as there is a brush selected
            // Whether or not it will be visible depends on which layer it's on and whether or not we're on a mobile
            // device. Mobile devices do not show the preview when the item was just clicked. The layer is changed later.
            Observable.EveryUpdate()
            .Where(ignored => isActiveAndEnabled)
            .Subscribe(ignored =>
            {
                if (brush.Value == null ||
                    Application.isMobilePlatform && !isDragAndDropping.Value)
                {
                    previewBrush.SetActive(false);
                    return;
                }

                previewBrush.SetActive(true);
                var pointer           = ContinuousStandaloneInputModule.instance.pointerEventData;
                var isOverDrawingView = pointer.pointerCurrentRaycast.gameObject ==
                                        m_DrawingView.raycastTarget.gameObject;

                previewImage.color = isDragAndDropping.Value ? isOverDrawingView ? opaque : transparent : opaque;
                previewBrushTransform.transform.position = BrushPosition(pointer);
            })
            .AddTo(this);


            // When we are drag and dropping, put the preview brush on the root canvas layer so that its totally in
            // the foreground. Otherwise, put it in the preview layer so it only appears when the user's pointer is
            // hovering over the drawing canvas
            isDragAndDropping.StartWith(false)
            .Subscribe(dragging =>
            {
                previewBrushTransform.SetParent(dragging ? m_ScreenRectTransform : m_DrawingView.previewLayer);
            })
            .AddTo(this);

            // Draw the brush when it is stamped
            var foreground = m_DrawingView.stampLayer;

            m_DrawingView.OnPointerClickAsObservable()
            .Where(ignored => brush.Value != null)
            .Subscribe(pointer => { Stamp(pointer, foreground, brush.Value.flipped); })
            .AddTo(this);

            // Enable drag and dropping a specific sprite. Temporarily switches the brush and activates drag and drop mode
            m_CataloguePagerView
            .OnCatalogueItemBeginDragAsObservable()
            .Subscribe(tuple =>
            {
                isDragAndDropping.Value = true;
                brush.Value             = new BrushItem()
                {
                    catalogueItem = tuple.Item2
                };
            })
            .AddTo(this);

            // Stamp when we stop dragging a catalogue item
            m_CataloguePagerView
            .OnCatalogueItemEndDragAsObservable()
            .Subscribe(tuple =>
            {
                isDragAndDropping.Value = false;
                // If we're over the drawing view, we should stamp the sprite
                var isOverDrawingView = tuple.Item1.pointerCurrentRaycast.gameObject ==
                                        m_DrawingView.raycastTarget.gameObject;
                if (isOverDrawingView)
                {
                    Stamp(tuple.Item1, m_DrawingView.stampLayer, tuple.Item2.flipped);
                }

                // Then clear the brush no matter what
                brush.Value = null;
            })
            .AddTo(this);

            // Toggle the flip automatically if this particular asset is configured to do so
            stampEvents.Where(stamp => stamp != null && stamp.brush.flipsAfterStamp)
            .Subscribe(stamp => { flipped.Value = !flipped.Value; })
            .AddTo(this);

            drawingView.stampItems.ObserveCountChanged(true)
            .Subscribe(count => { m_CanUndo.Value = count > 0; })
            .AddTo(this);

            // Save as the user stamps
            stampEvents
            .Subscribe(stampEvent =>
            {
                // This throttles internally
                SaveGameController.instance.Save();

                if (stampEvent != null)
                {
                    // Analytics
                    var hit = new EventHitBuilder()
                              .SetEventCategory("profile creator")
                              .SetEventAction("stamp")
                              .SetEventLabel(stampEvent.brush.sprite.name)
                              .SetEventValue(drawingView.stampItems.Count);
                    GoogleAnalyticsV4.getInstance().LogEvent(hit);
                }
            })
            .AddTo(this);
        }
Esempio n. 2
0
    public override void OnEnable()
    {
        base.OnEnable();

        SceneManager.sceneLoaded   += OnSceneLoaded;
        SceneManager.sceneUnloaded += OnSceneUnloaded;

        sceneLoaders.OnAdd().Subscribe(entity =>
        {
            var sceneLoader = entity.GetComponent <SceneLoader>();

            entity.OnListenerAsObservable <TriggerEnterEvent>().Select(_ => true)
            .Merge(entity.OnListenerAsObservable().Select(_ => true))
            .Subscribe(_ =>
            {
                foreach (var setup in sceneLoader.LoadQueue)
                {
                    if (setup.Operation == SceneLoader.Operation.Load)
                    {
                        EventSystem.Send(new LoadSceneEvent(setup.SceneSetup));
                    }
                    else if (setup.Operation == SceneLoader.Operation.Unload)
                    {
                        EventSystem.Send(new UnloadSceneEvent(setup.SceneSetup));
                    }
                }
            }).AddTo(this.Disposer).AddTo(sceneLoader.Disposer);
        }).AddTo(this.Disposer);

        loadingScreens.OnAdd().Subscribe(entity =>
        {
            var loadingScreen = entity.GetComponent <LoadingScreen>();

            loadingScreen.State.DistinctUntilChanged().Where(state => state == FadeState.FadedOut).Subscribe(_ =>
            {
                if (loadingScreens.Entities.Select(e => e.GetComponent <LoadingScreen>().State.Value).All(state => state != FadeState.FadingIn && state != FadeState.FadingOut))
                {
                    readyToLoad.Value = true;
                }
            }).AddTo(this.Disposer).AddTo(loadingScreen.Disposer);
        }).AddTo(this.Disposer);

        EventSystem.OnEvent <LoadSceneEvent>().Subscribe(evt =>
        {
            foreach (var setup in evt.LoadSceneSetup.Setups)
            {
                if ((setup.Mode == LoadSceneMode.Additive && SceneManager.GetSceneByPath(setup.Path).isLoaded) || scenesToLoad.Contains(setup))
                {
                    continue;
                }
                scenesToLoad.Add(setup);
            }
        }).AddTo(this.Disposer);

        EventSystem.OnEvent <UnloadSceneEvent>().Subscribe(evt =>
        {
            foreach (var setup in evt.UnloadSceneSetup.Setups)
            {
                var scene = SceneManager.GetSceneByPath(setup.Path);
                if (!scene.IsValid() || !scene.isLoaded || scenesToUnload.Contains(setup))
                {
                    continue;
                }
                scenesToUnload.Add(setup);
            }
        }).AddTo(this.Disposer);

        EventSystem.OnEvent <LoadSceneEvent>().Select(evt => evt.LoadSceneSetup).Merge(EventSystem.OnEvent <UnloadSceneEvent>().Select(evt => evt.UnloadSceneSetup))
        .Where(_ => !readyToLoad.Value && scenesToLoad.Count + scenesToUnload.Count > 0).Subscribe(setup =>
        {
            var isReady = true;
            foreach (var loadingScreen in loadingScreens.Entities.Select(entity => entity.GetComponent <LoadingScreen>()))
            {
                if (setup.LoadingMask.Contains(loadingScreen.Layer))
                {
                    loadingScreen.State.Value = FadeState.FadingOut;
                    isReady = false;
                }
            }
            readyToLoad.Value = isReady;
        }).AddTo(this.Disposer);

        scenesToLoad.ObserveAdd().Subscribe(evt =>
        {
            readyToLoad.StartWith(readyToLoad.Value).Where(isReady => isReady).FirstOrDefault().Subscribe(_ =>
            {
                SceneManager.LoadSceneAsync(evt.Value.Path, evt.Value.Mode);
            }).AddTo(this.Disposer);
        }).AddTo(this.Disposer);

        scenesToUnload.ObserveAdd().Subscribe(evt =>
        {
            readyToLoad.StartWith(readyToLoad.Value).Where(isReady => isReady).FirstOrDefault().Subscribe(_ =>
            {
                SceneManager.UnloadSceneAsync(evt.Value.Path);
            }).AddTo(this.Disposer);
        }).AddTo(this.Disposer);

        scenesToLoad.ObserveRemove().Merge(scenesToUnload.ObserveRemove())
        .Where(_ => scenesToLoad.Count <= 0 && scenesToUnload.Count <= 0)
        .Subscribe(_ =>
        {
            readyToLoad.Value = false;

            Resources.UnloadUnusedAssets();

            foreach (var loadingScreen in loadingScreens.Entities.Select(entity => entity.GetComponent <LoadingScreen>()).Where(loadingScreen => loadingScreen.State.Value == FadeState.FadingOut || loadingScreen.State.Value == FadeState.FadedOut))
            {
                loadingScreen.State.Value = FadeState.FadingIn;
            }
        }).AddTo(this.Disposer);
    }
Esempio n. 3
0
        protected override void Awake()
        {
            base.Awake();

            var version     = new IntReactiveProperty(0);
            var sentVersion = -1;

            responses.Observe()
            .Subscribe(ignored => { version.Value = version.Value + 1; })
            .AddTo(this);


            for (var i = 0; i < m_ChatBoxViews.Length; i++)
            {
                var j    = i;
                var view = m_ChatBoxViews[i];
                view.button.OnPointerClickAsObservable()
                .Where(ignored => view.button.interactable)
                .Subscribe(v =>
                {
                    if (m_PostOwnMessages)
                    {
                        m_ConversationController.Add(new ChatMessage[]
                        {
                            new ChatMessage()
                            {
                                self = true, message = view.data
                            }
                        });
                    }

                    SetChatBoxesInteractive(false);
                    sentVersion = version.Value;

                    m_Choices.OnNext(new ChatBoxChoice()
                    {
                        index = j,
                        text  = view.data
                    });
                })
                .AddTo(view);
            }

            m_InputBox.OnPointerClickAsObservable()
            .Where(ignored => !m_IsRequestingTextInput)
            .Subscribe(ignored =>
            {
                m_Open.Value = !m_Open.Value;
                m_ConversationController.ThrottledScrollToBottom();
            })
            .AddTo(this);

            Observable.Merge(
                responses.Observe().AsUnitObservable(),
                m_Open.StartWith(false).AsUnitObservable())
            .BatchFrame(1, FrameCountType.Update)
            .Subscribe(ignored =>
            {
                var count  = responses.Count;
                var isOpen = m_Open.Value;

                if (count == 0)
                {
                    isOpen = false;
                }
                else
                {
                    if (m_Open.Value)
                    {
                        m_ConversationController.StartTyping(true);
                    }
                    else
                    {
                        m_ConversationController.StopTyping();
                    }
                }

                for (var i = 0; i < m_ChatBoxViews.Length; i++)
                {
                    if (i < count)
                    {
                        m_ChatBoxViews[i].data = responses[i];
                    }
                    else
                    {
                        m_ChatBoxViews[i].data = null;
                    }

                    m_ChatBoxViews[i].gameObject.SetActive(isOpen && i < count);
                }

                m_InputBox.interactable = count > 0;
                SetChatBoxesInteractive(version.Value != sentVersion);
            })
            .AddTo(this);

            // The input text that this has is only enabled when the user actually has to type something in.
            m_SpacerForKeyboard.gameObject.SetActive(false);
            m_KeyboardConnector.enabled = false;
        }