public override IEnumerator ShowOverlayViewPageBase(ViewPage vp, bool RePlayOnShowWhileSamePage, Action OnStart, Action OnChanged, Action OnComplete, bool ignoreTimeScale) { // Debug.Log("ShowOverlayViewPageBase " + vp.name); if (vp == null) { ViewSystemLog.Log("ViewPage is null"); yield break; } if (vp.viewPageType != ViewPage.ViewPageType.Overlay) { ViewSystemLog.LogError("ViewPage " + vp.name + " is not an Overlay page"); yield break; } //Prepare runtime page root string viewPageRootName = ViewSystemUtilitys.GetPageRootName(vp); var pageWrapper = ViewSystemUtilitys.CreatePageTransform(viewPageRootName, rootCanvasTransform, vp.canvasSortOrder); if (vp.runtimePageRoot == null) { vp.runtimePageRoot = pageWrapper.rectTransform; } pageWrapper.safePadding.SetPaddingValue(vp.edgeValues); ViewState viewState = null; viewStates.TryGetValue(vp.viewState, out viewState); List <ViewElement> viewElementDoesExitsInNextPage = new List <ViewElement>(); IEnumerable <ViewPageItem> viewItemNextPage = null; IEnumerable <ViewPageItem> viewItemNextState = null; List <ViewPageItem> viewItemForNextPage = new List <ViewPageItem>(); string OverlayPageStateKey = GetOverlayStateKey(vp); bool samePage = false; //檢查是否有同 State 的 Overlay 頁面在場上 if (overlayPageStatusDict.TryGetValue(OverlayPageStateKey, out ViewSystemUtilitys.OverlayPageStatus overlayPageStatus)) { viewItemNextPage = PrepareRuntimeReference(GetAllViewPageItemInViewPage(vp)); //同 OverlayState 的頁面已經在場上,移除不同的部分,然後顯示新加入的部分 if (!string.IsNullOrEmpty(vp.viewState)) { if (overlayPageStatus.viewPage.name != vp.name) { // 同 State 不同 Page 的情況,找到差異的部分 foreach (var item in overlayPageStatus.viewPage.viewPageItems) { if (!vp.viewPageItems.Select(m => m.runtimeViewElement).Contains(item.runtimeViewElement)) { viewElementDoesExitsInNextPage.Add(item.runtimeViewElement); } } overlayPageStatus.viewPage = vp; } } else { //只有 ViewPage 卻還是進來這裡的話代表頁面還在場上 // RePlayOnShowWhileSamePage == false 那就更新數值 所以停掉舊的 Coroutine if (overlayPageStatus.pageChangeCoroutine != null) { StopCoroutine(overlayPageStatus.pageChangeCoroutine); } samePage = true; overlayPageStatus.transition = ViewSystemUtilitys.OverlayPageStatus.Transition.Show; } } else { //同 OverlayState 的頁面還不在場上 新建一個 Status overlayPageStatus = new ViewSystemUtilitys.OverlayPageStatus(); overlayPageStatus.viewPage = vp; overlayPageStatus.viewState = viewState; overlayPageStatus.transition = ViewSystemUtilitys.OverlayPageStatus.Transition.Show; viewItemNextPage = PrepareRuntimeReference(GetAllViewPageItemInViewPage(vp)); // 沒有 viewState 的 Page 不需要處理 viewState 的 runtimeViewElement if (!string.IsNullOrEmpty(vp.viewState)) { // nextViewState = viewStates.SingleOrDefault(m => m.name == vp.viewState); if (viewStates.TryGetValue(vp.viewState, out nextViewState)) { viewItemNextState = GetAllViewPageItemInViewState(nextViewState); viewItemNextState = PrepareRuntimeReference(viewItemNextState); } } overlayPageStatusDict.Add(OverlayPageStateKey, overlayPageStatus); } OnStart?.Invoke(); float onShowTime = ViewSystemUtilitys.CalculateOnShowDuration(viewItemNextPage.Select(m => m.runtimeViewElement)); float onShowDelay = ViewSystemUtilitys.CalculateDelayInTime(viewItemNextPage); //對離場的呼叫改變狀態 foreach (var item in viewElementDoesExitsInNextPage) { Debug.LogWarning($"{item.name} not exsit in next page"); item.ChangePage(false, null, null, 0, 0, 0); } viewItemForNextPage.AddRange(viewItemNextPage); if (viewItemNextState != null) { viewItemForNextPage.AddRange(viewItemNextState); } //對進場的呼叫改變狀態 foreach (var item in viewItemNextPage) { if (RePlayOnShowWhileSamePage && samePage) { item.runtimeViewElement.OnShow(); continue; } //套用複寫值 item.runtimeViewElement.ApplyOverrides(item.overrideDatas); item.runtimeViewElement.ApplyEvent(item.eventDatas); var transformData = item.GetCurrentViewElementTransform(breakPointsStatus); if (!string.IsNullOrEmpty(transformData.parentPath)) { item.runtimeParent = transformCache.Find(transformData.parentPath); } else { item.runtimeParent = vp.runtimePageRoot; } item.runtimeViewElement.ChangePage(true, item.runtimeParent, transformData, item.sortingOrder, item.TweenTime, item.delayIn, reshowIfSamePage: RePlayOnShowWhileSamePage); } SetNavigationTarget(vp); yield return(runtimePool.RecoveryQueuedViewElement()); //Fire the event OnChanged?.Invoke(); InvokeOnOverlayPageShow(this, new ViewPageEventArgs(vp, null)); //當所有表演都結束時 if (ignoreTimeScale) { yield return(Yielders.GetWaitForSecondsRealtime(onShowTime + onShowDelay)); } else { yield return(Yielders.GetWaitForSeconds(onShowTime + onShowDelay)); } overlayPageStatus.IsTransition = false; OnComplete?.Invoke(); }
public override IEnumerator ChangePageBase(string viewPageName, Action OnStart, Action OnChanged, Action OnComplete, bool ignoreTimeScale) { //取得 ViewPage 物件 // ViewPage nextViewPage; //沒有找到 if (!viewPages.TryGetValue(viewPageName, out nextViewPage)) { ViewSystemLog.LogError("No view page match " + viewPageName + " Found"); ChangePageToCoroutine = null; yield break; } if (nextViewPage.viewPageType == ViewPage.ViewPageType.Overlay) { ViewSystemLog.LogWarning("To shown Page is an Overlay ViewPage use ShowOverlayViewPage() instead method \n current version will redirect to this method automatically, but this behaviour may be changed in future release."); ShowOverlayViewPageBase(nextViewPage, true, OnStart, OnChanged, OnComplete, ignoreTimeScale); ChangePageToCoroutine = null; yield break; } //Prepare runtime page root string viewPageRootName = ViewSystemUtilitys.GetPageRootName(nextViewPage); var pageWrapper = ViewSystemUtilitys.CreatePageTransform(viewPageRootName, rootCanvasTransform, nextViewPage.canvasSortOrder); if (nextViewPage.runtimePageRoot == null) { nextViewPage.runtimePageRoot = pageWrapper.rectTransform; } pageWrapper.safePadding.SetPaddingValue(nextViewPage.edgeValues); //所有檢查都通過開始換頁 //IsPageTransition = true; nextViewState = null; viewStates.TryGetValue(nextViewPage.viewState, out nextViewState); IEnumerable <ViewPageItem> viewItemNextPage = PrepareRuntimeReference(GetAllViewPageItemInViewPage(nextViewPage)); IEnumerable <ViewPageItem> viewItemNextState = GetAllViewPageItemInViewState(nextViewState); List <ViewPageItem> viewItemForNextPage = new List <ViewPageItem>(); // 如果兩個頁面之間的 ViewState 不同的話 才需要更新 ViewState 部分的 RuntimeViewElement if (nextViewState != currentViewState) { viewItemNextState = PrepareRuntimeReference(viewItemNextState); } // All reference preparing is done start do the stuff for change page InvokeOnViewPageChangeStart(this, new ViewPageTrisitionEventArgs(currentViewPage, nextViewPage)); OnStart?.Invoke(); List <ViewElement> viewElementDoesExitsInNextPage = new List <ViewElement>(); var allViewElementForNextPageInViewPage = viewItemNextPage.Select(m => m.runtimeViewElement).ToList(); var allViewElementForNextPageInViewState = viewItemNextState.Select(m => m.runtimeViewElement).ToList(); foreach (var item in currentLiveElementsInViewPage) { //不存在的話就讓他加入應該移除的列表 if (allViewElementForNextPageInViewPage.Contains(item) == false && allViewElementForNextPageInViewState.Contains(item) == false) { //加入該移除的列表 viewElementDoesExitsInNextPage.Add(item); } } currentLiveElementsInViewPage.Clear(); currentLiveElementsInViewPage = allViewElementForNextPageInViewPage; if (nextViewState != currentViewState) { foreach (var item in currentLiveElementsInViewState) { //不存在的話就讓他加入應該移除的列表 if (allViewElementForNextPageInViewState.Contains(item) == false && allViewElementForNextPageInViewPage.Contains(item) == false) { //加入該移除的列表 viewElementDoesExitsInNextPage.Add(item); } } currentLiveElementsInViewState.Clear(); currentLiveElementsInViewState = allViewElementForNextPageInViewState; } //對離場的呼叫改變狀態 foreach (var item in viewElementDoesExitsInNextPage) { item.ChangePage(false, null, null, 0, 0); } float TimeForPerviousPageOnLeave = 0; switch (nextViewPage.viewPageTransitionTimingType) { case ViewPage.ViewPageTransitionTimingType.AfterPervious: //TimeForPerviousPageOnLeave = ViewSystemUtilitys.CalculateOnLeaveDuration(viewItemNextPage.Select(m => m.viewElement), maxClampTime); TimeForPerviousPageOnLeave = nextViewPageWaitTime; break; case ViewPage.ViewPageTransitionTimingType.WithPervious: TimeForPerviousPageOnLeave = 0; break; case ViewPage.ViewPageTransitionTimingType.Custom: TimeForPerviousPageOnLeave = nextViewPage.customPageTransitionWaitTime; break; } // nextViewPageWaitTime = ViewSystemUtilitys.CalculateDelayOutTime(viewItemNextPage); nextViewPageWaitTime = ViewSystemUtilitys.CalculateOnLeaveDuration(viewItemNextPage.Select(m => m.viewElement), maxClampTime); //等上一個頁面的 OnLeave 結束,注意,如果頁面中有大量的 Animator 這裡只能算出預估的結果 並且會限制最長時間為一秒鐘 if (ignoreTimeScale) { yield return(Yielders.GetWaitForSecondsRealtime(TimeForPerviousPageOnLeave)); } else { yield return(Yielders.GetWaitForSeconds(TimeForPerviousPageOnLeave)); } viewItemForNextPage.AddRange(viewItemNextPage); if (viewItemNextState != null) { viewItemForNextPage.AddRange(viewItemNextState); } //對進場的呼叫改變狀態(ViewPage) foreach (var item in viewItemForNextPage.OrderBy(m => m.sortingOrder)) { if (item.runtimeViewElement == null) { ViewSystemLog.LogError($"The runtimeViewElement is null for some reason, ignore this item."); continue; } //套用複寫值 item.runtimeViewElement.ApplyOverrides(item.overrideDatas); item.runtimeViewElement.ApplyEvent(item.eventDatas); var transformData = item.GetCurrentViewElementTransform(breakPointsStatus); if (!string.IsNullOrEmpty(transformData.parentPath)) { item.runtimeParent = transformCache.Find(transformData.parentPath); } else { item.runtimeParent = nextViewPage.runtimePageRoot; } item.runtimeViewElement.ChangePage(true, item.runtimeParent, transformData, item.sortingOrder, item.TweenTime, item.delayIn); } foreach (var item in currentLiveElements.OrderBy(m => m.sortingOrder)) { item.rectTransform.SetAsLastSibling(); } float OnShowAnimationFinish = ViewSystemUtilitys.CalculateOnShowDuration(viewItemNextPage.Select(m => m.runtimeViewElement), maxClampTime); //更新狀態 UpdateCurrentViewStateAndNotifyEvent(nextViewPage); foreach (var item in currentLiveElements) { item.OnChangedPage(); } yield return(runtimePool.RecoveryQueuedViewElement()); OnChanged?.Invoke(); if (ignoreTimeScale) { yield return(Yielders.GetWaitForSecondsRealtime(OnShowAnimationFinish)); } else { //通知事件 yield return(Yielders.GetWaitForSeconds(OnShowAnimationFinish)); } ChangePageToCoroutine = null; //Callback InvokeOnViewPageChangeEnd(this, new ViewPageEventArgs(currentViewPage, lastViewPage)); nextViewPage = null; nextViewState = null; //2019.12.18 due to there may be new Callback be add, change the OnComplete to all is done. OnComplete?.Invoke(); }