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); }
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); } }
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); } }