| | |
| | | using System.Collections.Generic; |
| | | using EnhancedUI.EnhancedScroller; |
| | | using UnityEngine; |
| | | using UnityEngine.UI; |
| | | |
| | | public class HeroTrialWin : UIBase |
| | | { |
| | | [SerializeField] HeroTrialCarouselView carouselView; |
| | | [SerializeField] ScrollerController heroScroller; |
| | | [SerializeField] ScrollerController scroller; |
| | | [SerializeField] float heroSelectTweenTime = 0.15f; |
| | | |
| | | List<int> heroIDs; |
| | | List<HeroTrialConfig> currentConfigs = new List<HeroTrialConfig>(); |
| | | int currentHeroIndex = -1; |
| | | uint currentHeroID; |
| | | byte currentPassLevelNum; |
| | | bool currentHeroUnlocked; |
| | | string currentHeroUnlockTip = string.Empty; |
| | | // OnPreOpen 首次打开时用于定位到红点关卡的 dataIndex;-1 表示不跳转。 |
| | | int jumpTargetDataIndex = -1; |
| | | bool needJumpToHeroAfterScrollerReady; |
| | | |
| | | protected override void InitComponent() |
| | | { |
| | |
| | | |
| | | protected override void OnPreOpen() |
| | | { |
| | | carouselView.InitPool(); |
| | | carouselView.BindEvents(); |
| | | carouselView.OnSelectedIndexChanged += OnSelectedIndexChanged; |
| | | |
| | | SetupHeroScroller(); |
| | | heroScroller.OnRefreshCell += OnRefreshHeroCell; |
| | | heroScroller.OnRefreshCompleteEvent += OnHeroScrollerRefreshComplete; |
| | | scroller.OnRefreshCell += OnRefreshCell; |
| | | HeroTrialManager.Instance.OnUpdateHeroTrialInfoEvent += OnHeroTrialInfoUpdate; |
| | | |
| | | carouselView.RefreshData(); |
| | | carouselView.InitWithIndex(GetDefaultHeroIndex()); |
| | | |
| | | RefreshHeroScroller(GetDefaultHeroIndex()); |
| | | RefreshScroller(); |
| | | } |
| | | |
| | | protected override void OnPreClose() |
| | | { |
| | | carouselView.UnbindEvents(); |
| | | carouselView.OnSelectedIndexChanged -= OnSelectedIndexChanged; |
| | | heroScroller.OnRefreshCell -= OnRefreshHeroCell; |
| | | heroScroller.OnRefreshCompleteEvent -= OnHeroScrollerRefreshComplete; |
| | | scroller.OnRefreshCell -= OnRefreshCell; |
| | | HeroTrialManager.Instance.OnUpdateHeroTrialInfoEvent -= OnHeroTrialInfoUpdate; |
| | | } |
| | | |
| | | void OnSelectedIndexChanged() |
| | | { |
| | | RefreshScroller(); |
| | | } |
| | | |
| | | void OnHeroTrialInfoUpdate() |
| | | { |
| | | int targetHeroIndex = -1; |
| | | int redHeroIndex = FindRedHeroIndex(); |
| | | if (redHeroIndex >= 0) |
| | | { |
| | | List<int> heroIDList = HeroTrialManager.Instance.GetHeroTrialHeroIDList(); |
| | | int redHeroID = heroIDList[redHeroIndex]; |
| | | if (carouselView.CurrentHeroID != redHeroID) |
| | | { |
| | | carouselView.SelectIndex(redHeroIndex); |
| | | return; |
| | | } |
| | | if (currentHeroID != redHeroID) |
| | | targetHeroIndex = redHeroIndex; |
| | | } |
| | | |
| | | RefreshHeroScroller(targetHeroIndex); |
| | | RefreshScroller(); |
| | | } |
| | | |
| | |
| | | return -1; |
| | | } |
| | | |
| | | void RefreshHeroScroller(int selectedIndex) |
| | | { |
| | | uint prevHeroID = currentHeroID; |
| | | heroIDs = HeroTrialManager.Instance.GetHeroTrialHeroIDList(); |
| | | |
| | | if (heroIDs.IsNullOrEmpty()) |
| | | { |
| | | currentHeroIndex = -1; |
| | | currentHeroID = 0; |
| | | heroScroller.Refresh(); |
| | | heroScroller.Restart(); |
| | | return; |
| | | } |
| | | |
| | | int heroIndex = selectedIndex; |
| | | if (heroIndex < 0) |
| | | heroIndex = FindHeroIndex(prevHeroID); |
| | | currentHeroIndex = Mathf.Clamp(heroIndex, 0, heroIDs.Count - 1); |
| | | currentHeroID = (uint)heroIDs[currentHeroIndex]; |
| | | |
| | | SetupHeroScroller(); |
| | | heroScroller.Refresh(); |
| | | for (int i = 0; i < heroIDs.Count; i++) |
| | | { |
| | | heroScroller.AddCell(ScrollerDataType.Header, i); |
| | | } |
| | | heroScroller.Restart(); |
| | | needJumpToHeroAfterScrollerReady = true; |
| | | JumpToCurrentHero(false); |
| | | } |
| | | |
| | | void SelectHeroIndex(int index) |
| | | { |
| | | if (heroIDs.IsNullOrEmpty()) |
| | | return; |
| | | |
| | | int oldIndex = currentHeroIndex; |
| | | currentHeroIndex = Mathf.Clamp(index, 0, heroIDs.Count - 1); |
| | | currentHeroID = (uint)heroIDs[currentHeroIndex]; |
| | | RefreshActiveHeroItems(); |
| | | JumpToCurrentHero(true); |
| | | |
| | | if (oldIndex != currentHeroIndex) |
| | | RefreshScroller(); |
| | | } |
| | | |
| | | void OnRefreshHeroCell(ScrollerDataType type, CellView cell) |
| | | { |
| | | _ = type; |
| | | |
| | | HeroTrialHeroItem heroItem = cell as HeroTrialHeroItem; |
| | | if (heroItem == null || heroIDs.IsNullOrEmpty()) |
| | | return; |
| | | |
| | | int dataIndex = Mathf.Clamp(cell.index, 0, heroIDs.Count - 1); |
| | | heroItem.UpdateData((uint)heroIDs[dataIndex], dataIndex, dataIndex == currentHeroIndex, SelectHeroIndex); |
| | | } |
| | | |
| | | void OnHeroScrollerRefreshComplete() |
| | | { |
| | | RefreshActiveHeroItems(); |
| | | |
| | | if (!needJumpToHeroAfterScrollerReady) |
| | | return; |
| | | |
| | | needJumpToHeroAfterScrollerReady = false; |
| | | JumpToCurrentHero(false); |
| | | } |
| | | |
| | | void RefreshActiveHeroItems() |
| | | { |
| | | List<CellView> activeCells = heroScroller.GetActiveCellViews(); |
| | | if (activeCells == null) |
| | | return; |
| | | |
| | | for (int i = 0; i < activeCells.Count; i++) |
| | | { |
| | | OnRefreshHeroCell(activeCells[i].type, activeCells[i]); |
| | | } |
| | | } |
| | | |
| | | void SetupHeroScroller() |
| | | { |
| | | heroScroller.horizontal = true; |
| | | heroScroller.vertical = false; |
| | | heroScroller.lockType = EnhanceLockType.None; |
| | | |
| | | heroScroller.m_Scorller.Loop = false; |
| | | heroScroller.m_Scorller.snapping = false; |
| | | heroScroller.m_Scorller.scrollDirection = EnhancedScroller.ScrollDirectionEnum.Horizontal; |
| | | |
| | | ScrollRect scrollRect = heroScroller.mScrollRect; |
| | | if (scrollRect != null) |
| | | { |
| | | scrollRect.horizontal = true; |
| | | scrollRect.vertical = false; |
| | | } |
| | | } |
| | | |
| | | void JumpToCurrentHero(bool useTween) |
| | | { |
| | | if (heroIDs.IsNullOrEmpty() || currentHeroIndex < 0) |
| | | return; |
| | | if (!heroScroller.m_Scorller.inited) |
| | | { |
| | | needJumpToHeroAfterScrollerReady = true; |
| | | return; |
| | | } |
| | | |
| | | float scrollerOffset = GetCurrentHeroScrollerOffset(); |
| | | EnhancedScroller.TweenType tweenType = useTween ? EnhancedScroller.TweenType.easeOutQuad : EnhancedScroller.TweenType.immediate; |
| | | float tweenTime = useTween ? heroSelectTweenTime : 0f; |
| | | heroScroller.m_Scorller.JumpToDataIndex(currentHeroIndex, scrollerOffset, 0.5f, true, tweenType, tweenTime, RefreshActiveHeroItems); |
| | | } |
| | | |
| | | float GetCurrentHeroScrollerOffset() |
| | | { |
| | | if (heroIDs.IsNullOrEmpty()) |
| | | return 0.5f; |
| | | |
| | | float viewportSize = Mathf.Max(1f, heroScroller.m_Scorller.ScrollRectSize); |
| | | float cellSize = Mathf.Max(1f, heroScroller.GetCellSize(currentHeroIndex)); |
| | | float halfCellOffset = cellSize * 0.5f / viewportSize; |
| | | |
| | | if (currentHeroIndex <= 0) |
| | | return halfCellOffset; |
| | | if (currentHeroIndex >= heroIDs.Count - 1) |
| | | return Mathf.Clamp01(1f - halfCellOffset); |
| | | return 0.5f; |
| | | } |
| | | |
| | | int FindHeroIndex(uint heroID) |
| | | { |
| | | if (heroID == 0 || heroIDs.IsNullOrEmpty()) |
| | | return -1; |
| | | |
| | | for (int i = 0; i < heroIDs.Count; i++) |
| | | { |
| | | if ((uint)heroIDs[i] == heroID) |
| | | return i; |
| | | } |
| | | |
| | | return -1; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据当前选中的武将,刷新下方的关卡Scroll |
| | | /// </summary> |
| | | void RefreshScroller() |
| | | { |
| | | currentConfigs.Clear(); |
| | | currentHeroID = carouselView.CurrentHeroID; |
| | | currentHeroUnlockTip = string.Empty; |
| | | currentHeroUnlocked = currentHeroID != 0 && HeroTrialManager.Instance.IsHeroTrialHeroUnlocked((int)currentHeroID, out currentHeroUnlockTip); |
| | | if (currentHeroID == 0 || !HeroTrialManager.Instance.TryGetHeroPassLevelNum(currentHeroID, out currentPassLevelNum)) |