Exemplo n.º 1
0
        private IEnumerator UpdateContentsInternal()
        {
            if (itemSize == -1)
            {
                var rt = UnityUtility.GetComponent <RectTransform>(itemPrefab);
                itemSize = direction == Direction.Vertical ? rt.rect.height : rt.rect.width;
            }

            // Contentのサイズ設定.
            scrollRect.content.anchorMin = direction == Direction.Vertical ? new Vector2(0f, 0.5f) : new Vector2(0.5f, 0f);
            scrollRect.content.anchorMax = direction == Direction.Vertical ? new Vector2(1f, 0.5f) : new Vector2(0.5f, 1f);
            scrollRect.content.pivot     = new Vector2(0.5f, 0.5f);

            // Hitboxは全域使用.
            if (hitBox != null)
            {
                hitBox.anchorMin = new Vector2(0f, 0f);
                hitBox.anchorMax = new Vector2(1f, 1f);
                hitBox.pivot     = new Vector2(0.5f, 0.5f);
            }

            switch (scrollType)
            {
            case ScrollType.Loop:
            {
                scrollRect.movementType = ScrollRect.MovementType.Unrestricted;

                var delta = scrollRectTransform.rect.size;

                if (direction == Direction.Vertical)
                {
                    delta.x = 0;
                }
                else
                {
                    delta.y = 0f;
                }

                scrollRect.content.sizeDelta = delta;
            }
            break;

            case ScrollType.Limited:
            {
                if (scrollRect.movementType == ScrollRect.MovementType.Unrestricted)
                {
                    scrollRect.movementType = ScrollRect.MovementType.Elastic;
                }

                var delta = scrollRect.content.sizeDelta;

                var sizeDelta = Mathf.Abs(edgeSpacing) * 2 + itemSize * Contents.Length + itemSpacing * (Contents.Length - 1);

                if (direction == Direction.Vertical)
                {
                    var scrollHeight = scrollRectTransform.rect.height;
                    delta.y = sizeDelta < scrollHeight ? scrollHeight : sizeDelta;
                }
                else
                {
                    var scrollWidth = scrollRectTransform.rect.width;
                    delta.x = sizeDelta < scrollWidth ? scrollWidth : sizeDelta;
                }

                scrollRect.content.sizeDelta = delta;
            }
            break;
            }

            var requireCount = GetRequireCount();

            // 配置初期位置(中央揃え想定なのでItemSize * 0.5f分ずらす).
            var basePosition = direction == Direction.Vertical ?
                               scrollRect.content.rect.height * 0.5f - itemSize * 0.5f - edgeSpacing :
                               -scrollRect.content.rect.width * 0.5f + itemSize * 0.5f + edgeSpacing;

            // 足りない分を生成.
            var createCount = requireCount - itemList.Count;
            var addItems    = UnityUtility.Instantiate <VirtualScrollItem <T> >(scrollRect.content.gameObject, itemPrefab, createCount, false);

            itemList.AddRange(addItems);

            // 先に登録して非アクティブ化.
            foreach (var item in addItems)
            {
                UnityUtility.SetActive(item, false);
            }

            // 生成したインスタンス初期化.
            foreach (var item in addItems)
            {
                UnityUtility.SetActive(item, true);

                if (onCreateItem != null)
                {
                    onCreateItem.OnNext(item.gameObject);
                }

                yield return(item.Initialize().ToYieldInstruction());

                UnityUtility.SetActive(item, false);
            }

            // 要素数が少ない時はスクロールを無効化.
            scrollRect.enabled = ScrollEnable();

            var scrollbar = direction == Direction.Vertical ? scrollRect.verticalScrollbar : scrollRect.horizontalScrollbar;

            if (scrollbar != null)
            {
                UnityUtility.SetActive(scrollbar.gameObject, ScrollEnable());
            }

            // 位置、情報を更新.
            for (var i = 0; i < itemList.Count; i++)
            {
                var item = itemList[i];

                var offset = itemSize * i;

                offset += 0 < i ? itemSpacing * i : 0;

                item.RectTransform.anchoredPosition = direction == Direction.Vertical ?
                                                      new Vector2(0, basePosition - offset) :
                                                      new Vector2(basePosition + offset, 0);

                UpdateItem(item, i);
            }

            // 並べ替え.
            UpdateSibling();

            // スクロール初期位置設定.
            CenterToItem(0);
        }
Exemplo n.º 2
0
        private IEnumerator UpdateContentsInternal(bool keepScrollPosition)
        {
            var scrollPosition = ScrollPosition;

            if (itemSize == -1)
            {
                var rt = UnityUtility.GetComponent <RectTransform>(itemPrefab);
                itemSize = direction == Direction.Vertical ? rt.rect.height : rt.rect.width;
            }

            //----- Contentのサイズ設定 -----

            scrollRect.content.anchorMin = direction == Direction.Vertical ? new Vector2(0f, 0.5f) : new Vector2(0.5f, 0f);
            scrollRect.content.anchorMax = direction == Direction.Vertical ? new Vector2(1f, 0.5f) : new Vector2(0.5f, 1f);
            scrollRect.content.pivot     = new Vector2(0.5f, 0.5f);

            var delta = scrollRectTransform.rect.size;

            switch (scrollType)
            {
            case ScrollType.Loop:
            {
                scrollRect.movementType = ScrollRect.MovementType.Unrestricted;

                // ※ UIScrollViewのautoScrollDisableに引っかからないように領域を拡張.

                if (direction == Direction.Vertical)
                {
                    delta.x  = 0f;
                    delta.y += 1f;
                }
                else
                {
                    delta.y  = 0f;
                    delta.x += 1f;
                }

                scrollRect.content.sizeDelta = delta;
            }
            break;

            case ScrollType.Limited:
            {
                if (scrollRect.movementType == ScrollRect.MovementType.Unrestricted)
                {
                    scrollRect.movementType = ScrollRect.MovementType.Elastic;
                }

                var sizeDelta = Mathf.Abs(edgeSpacing) * 2 + itemSize * Contents.Count + itemSpacing * (Contents.Count - 1);

                if (direction == Direction.Vertical)
                {
                    var scrollHeight = scrollRectTransform.rect.height;
                    delta.x = 0f;
                    delta.y = sizeDelta < scrollHeight ? scrollHeight : sizeDelta;
                }
                else
                {
                    var scrollWidth = scrollRectTransform.rect.width;
                    delta.x = sizeDelta < scrollWidth ? scrollWidth : sizeDelta;
                    delta.y = 0f;
                }

                scrollRect.content.sizeDelta = delta;
            }
            break;
            }

            //----- ヒットボックス初期化 -----

            SetupHitBox();

            //----- 足りない分を生成 -----

            var requireCount = GetRequireCount();

            var createCount = requireCount - itemList.Count;

            if (0 < createCount)
            {
                var addItems = UnityUtility.Instantiate <VirtualScrollItem <T> >(scrollRect.content.gameObject, itemPrefab, createCount).ToArray();

                itemList.AddRange(addItems);

                // 全アイテム非アクティブ化.
                addItems.ForEach(x => UnityUtility.SetActive(x, false));

                // 生成したインスタンス初期化.

                var initializeObservers = new IObservable <Unit> [addItems.Length];

                for (var i = 0; i < addItems.Length; i++)
                {
                    var item = addItems[i];

                    initializeObservers[i] = Observable.Defer(() => Observable.FromMicroCoroutine(() => InitializeItem(item)));
                }

                var initializeYield = initializeObservers.WhenAll().ToYieldInstruction(false);

                while (!initializeYield.IsDone)
                {
                    yield return(null);
                }

                if (initializeYield.HasError)
                {
                    Debug.LogException(initializeYield.Error);
                }
            }

            // 要素数が少ない時はスクロールを無効化.
            scrollRect.enabled = ScrollEnable();

            var scrollbar = direction == Direction.Vertical ? scrollRect.verticalScrollbar : scrollRect.horizontalScrollbar;

            if (scrollbar != null)
            {
                UnityUtility.SetActive(scrollbar.gameObject, ScrollEnable());
            }

            var updateObservers = new IObservable <Unit> [itemList.Count];

            // 配置初期位置(中央揃え想定なのでItemSize * 0.5f分ずらす).
            var basePosition = direction == Direction.Vertical ?
                               scrollRect.content.rect.height * 0.5f - itemSize * 0.5f - edgeSpacing :
                               -scrollRect.content.rect.width * 0.5f + itemSize * 0.5f + edgeSpacing;

            // 位置、情報を更新.
            for (var i = 0; i < itemList.Count; i++)
            {
                var index = i;
                var item  = itemList[i];

                var offset = itemSize * i;

                offset += 0 < i ? itemSpacing * i : 0;

                item.RectTransform.anchoredPosition = direction == Direction.Vertical ?
                                                      new Vector2(0, basePosition - offset) :
                                                      new Vector2(basePosition + offset, 0);

                updateObservers[i] = Observable.Defer(() => UpdateItem(item, index));
            }

            //----- リストアイテム更新 -----

            var updateItemYield = updateObservers.WhenAll().ToYieldInstruction(false);

            while (!updateItemYield.IsDone)
            {
                yield return(null);
            }

            if (updateItemYield.HasError)
            {
                Debug.LogException(updateItemYield.Error);
            }

            //----- スクロール位置設定 -----

            if (keepScrollPosition)
            {
                ScrollPosition = scrollPosition;
            }
            else
            {
                ScrollToItem(0, ScrollTo.First);
            }

            //----- 並べ替え -----

            UpdateSibling();

            //-----  更新イベント -----

            OnUpdateContents();

            if (onUpdateContents != null)
            {
                onUpdateContents.OnNext(Unit.Default);
            }
        }
Exemplo n.º 3
0
        protected void UpdateContents()
        {
            var        touchBlocIndex = 0;
            GameObject parent         = null;

            if (touchBloc == null)
            {
                touchBloc = UnityUtility.Instantiate <TouchBloc>(parentGlobal.Parent, touchBlocPrefab);
                touchBloc.Initialize();
            }

            if (scenePopups.Any())
            {
                var index = 0;

                parent         = parentInScene.Parent;
                touchBlocIndex = 0;

                foreach (var item in scenePopups)
                {
                    if (item == scenePopups.LastOrDefault())
                    {
                        touchBlocIndex = index++;
                    }

                    item.transform.SetSiblingIndex(index++);
                }
            }

            if (globalPopups.Any())
            {
                var index = 0;

                parent         = parentGlobal.Parent;
                touchBlocIndex = 0;

                foreach (var item in globalPopups)
                {
                    if (item == globalPopups.LastOrDefault())
                    {
                        touchBlocIndex = index++;
                    }

                    item.transform.SetSiblingIndex(index++);
                }
            }

            // ポップアップがなかった場合はグローバルの下に退避.
            if (parent == null)
            {
                parent = parentGlobal.Parent;
            }

            UnityUtility.SetParent(touchBloc.gameObject, parent);

            touchBloc.transform.SetSiblingIndex(touchBlocIndex);

            UnityUtility.SetLayer(parent, touchBloc.gameObject, true);

            // 一つでも登録されたら表示.
            if (!touchBloc.Active && (scenePopups.Any() || globalPopups.Any()))
            {
                if (touchBlocDisposable != null)
                {
                    touchBlocDisposable.Dispose();
                    touchBlocDisposable = null;
                }

                touchBlocDisposable = touchBloc.FadeIn().Subscribe().AddTo(this);
            }

            // 空になったら非表示.
            if (touchBloc.Active && (scenePopups.IsEmpty() && globalPopups.IsEmpty()))
            {
                if (touchBlocDisposable != null)
                {
                    touchBlocDisposable.Dispose();
                    touchBlocDisposable = null;
                }

                touchBlocDisposable = touchBloc.FadeOut().Subscribe().AddTo(this);
            }
        }