hch
2 天以前 87d5c46997d61523aed87fdb7ed0b07e9dded223
Main/System/HeroUI/HeroPosWin.cs
@@ -2,14 +2,20 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using Cysharp.Threading.Tasks;
using System.Threading;
using System;
/// <summary>
/// 武将布阵: functionOrder:布阵类型
/// 武将布阵界面
/// </summary>
public class HeroPosWin : UIBase
{
    [SerializeField] Text[] attrOnList; //上阵属性加成
    [SerializeField] Button countryOnBtn;
    [SerializeField] Image countryOnImg;    //上阵阵型激活国家
    [SerializeField] UIEffectPlayer countryEffect;
    [SerializeField] List<Image> OnCountImgs;    //上阵数量激活
    [SerializeField] List<Image> scenePosImgs;  //场景布阵位置
    [SerializeField] HeroScenePosCell[] sceneHero;
@@ -21,77 +27,182 @@
    [SerializeField] ScrollerController heroListScroller;
    [SerializeField] Transform heroListEmpty;
    [SerializeField] Toggle showConnTipToggleBtn;
    [SerializeField] HeroSelectBehaviour fiterManager;  //武将筛选
    [SerializeField] Button oneKeyOnBtn;     //一键上阵
    [SerializeField] Button saveBtn;        //保存阵型
    [SerializeField] Button backBtn;      //退出界面
    [SerializeField] GroupButtonEx jjcBtn;       //竞技场
    [SerializeField] GroupButtonEx tttBtn;        //通天塔
    // [SerializeField] GroupButtonEx tttBtn;        //通天塔
    [SerializeField] GroupButtonEx mainFBBtn;     //主线副本
    //羁绊
    [SerializeField] HeroConnectionCell connetionForm;
    [SerializeField] HeroHeadBaseCell flyHead;
    [SerializeField] CanvasGroup flyAlphaTween;
    Sequence sequence;
    CancellationTokenSource _cts;
    Queue<int> showConnectTipQueue = new Queue<int>();
    private bool m_IsToggleOn = false;
    private bool isToggleOn
    {
        get { return m_IsToggleOn; }
        set
        {
            if (m_IsToggleOn != value)
            {
                m_IsToggleOn = value;
                LocalSave.SetBool("ShowConn" + PlayerDatas.Instance.baseData.PlayerID, value);
            }
        }
    }
    protected override void InitComponent()
    {
        attackTeamBtn.AddListener(() =>
        {
            if (HeroUIManager.Instance.selectTeamType == TeamType.Arena)
            {
                return;
            }
            HeroUIManager.Instance.selectTeamType = TeamType.Arena;
            Refresh();
            SelectTeamFunc((TeamType)HeroUIManager.Instance.GetSelectTeamTypeByAttackType(0));
        });
        defendTeamBtn.AddListener(() =>
        {
            if (HeroUIManager.Instance.selectTeamType == TeamType.ArenaDefense)
            {
                return;
            }
            HeroUIManager.Instance.selectTeamType = TeamType.ArenaDefense;
            Refresh();
            SelectTeamFunc((TeamType)HeroUIManager.Instance.GetSelectTeamTypeByAttackType(1));
        });
        mainFBBtn.AddListener(() =>
        {
            SelectTeamFunc(TeamType.Story);
        });
        jjcBtn.AddListener(() =>
        {
            SelectTeamFunc(TeamType.Arena);
        });
        // tttBtn.AddListener(() =>
        // {
        //     SelectTeamFunc(TeamType.Tower);
        // });
        showConnTipToggleBtn.AddListener((value) =>
        {
            isToggleOn = showConnTipToggleBtn.isOn;
            if (isToggleOn == false)
            {
                CancelCurrentTask();
            }
        });
        oneKeyOnBtn.AddListener(OneKeyOnPos);
        saveBtn.AddListener(SaveTeam);
        backBtn.AddListener(CloseWindow);
        countryOnBtn.AddListener(() =>
        {
            UIManager.Instance.OpenWindow<HeroFormationWin>();
        });
        m_IsToggleOn = LocalSave.GetBool("ShowConn" + PlayerDatas.Instance.baseData.PlayerID, false);
    }
    protected override void OnPreOpen()
    {
        HeroUIManager.Instance.selectTeamPosJob = 0;
        HeroUIManager.Instance.selectTeamPosCountry = 0;
        HeroUIManager.Instance.SortHeroOnTeamList();
        heroListScroller.OnRefreshCell += OnRefreshCell;
        HeroUIManager.Instance.OnTeamPosChangeEvent += TeamChangeEvent;
        TeamManager.Instance.OnTeamChange += OnTeamChange;
        CreateScroller();
        Refresh();
        Display();
    }
    protected override void OnPreClose()
    {
        CancelCurrentTask();
        heroListScroller.OnRefreshCell -= OnRefreshCell;
        HeroUIManager.Instance.OnTeamPosChangeEvent -= TeamChangeEvent;
        TeamManager.Instance.OnTeamChange -= OnTeamChange;
        TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType).RestoreTeam();
    }
    public override void Refresh()
    public void Display()
    {
        OnBattleTeamAttrPer();
        RefreshOnTeamCountry();
        RefreshOnTeamBtn();
        RefreshTeamHero();
        RefreshFlyHead();
        RefreshConn();
        RefreshEmptyTip();
        showConnTipToggleBtn.isOn = isToggleOn;
        fiterManager.Display(0, HeroUIManager.Instance.selectTeamPosJob, HeroUIManager.Instance.selectTeamPosCountry, SelectJobCountry);
        fightPowerText.text = UIHelper.ReplaceLargeArtNum(FightPowerManager.Instance.GetTeamFightPower(HeroUIManager.Instance.selectTeamType, true));
    }
    void RefreshFlyHead()
    {
        var flyCanvas = flyAlphaTween.GetComponent<Canvas>();
        flyCanvas.sortingLayerID = canvas.sortingLayerID;
        flyCanvas.sortingOrder = canvas.sortingOrder + 9;
        flyAlphaTween.alpha = 0;
        flyHead.transform.localScale = Vector3.zero;
    }
    void RefreshConn()
    {
        connetionForm.SetActive(false);
        var canvasConn = connetionForm.GetComponent<Canvas>();
        canvasConn.sortingLayerID = canvas.sortingLayerID;
        canvasConn.sortingOrder = canvas.sortingOrder + 9;
        CancelCurrentTask();
    }
    void SelectJobCountry(int job, int country)
    {
        HeroUIManager.Instance.selectTeamPosJob = job;
        HeroUIManager.Instance.selectTeamPosCountry = country;
        HeroUIManager.Instance.SortHeroOnTeamList();
        CreateScroller();
        RefreshEmptyTip();
    }
    void RefreshEmptyTip()
    {
        if (HeroUIManager.Instance.heroOnTeamSortList.Count <= 0)
        {
            heroListEmpty.SetActive(true);
            heroListScroller.SetActive(false);
        }
        else
        {
            heroListEmpty.SetActive(false);
            heroListScroller.SetActive(true);
        }
    }
    void OnRefreshCell(ScrollerDataType type, CellView cell)
    {
        var _cell = cell as HeroCardLineCell;
        var _cell = cell as HeroPosLineCell;
        _cell.Display(cell.index);
    }
    void CreateScroller()
    {
        heroListScroller.Refresh();
        for (int i = 0; i < HeroUIManager.Instance.heroSortList.Count; i++)
        for (int i = 0; i < HeroUIManager.Instance.heroOnTeamSortList.Count; i++)
        {
            if (i % 4 == 0)
            if (i % 5 == 0)
            {
                heroListScroller.AddCell(ScrollerDataType.Header, i);
            }
@@ -106,9 +217,11 @@
        var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType);
        if (team != null)
        {
            for (int i = 0; i < team.serverHeroes.Length; i++)
            for (int i = 0; i < team.tempHeroes.Length; i++)
            {
                var hero = HeroManager.Instance.GetHero(team.serverHeroes[i].guid);
                if (team.tempHeroes[i] == null)
                    continue;
                var hero = HeroManager.Instance.GetHero(team.tempHeroes[i].guid);
                if (hero != null)
                {
                    valuePer += hero.GetOnBattleAddPer();
@@ -119,19 +232,20 @@
        //上阵属性
        for (int i = 0; i < attrOnList.Length; i++)
        {
            attrOnList[i].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.basePerAttrs[i], valuePer));
            string format = valuePer == 0 ? "{0}+{1}" : "{0}+" + UIHelper.AppendColor(TextColType.Green, "{1}", false);
            attrOnList[i].text = PlayerPropertyConfig.GetFullDescription(PlayerPropertyConfig.basePerAttrs[i], valuePer, format);
        }
    }
    //上阵武将国家光环激活
    void RefreshOnTeamCountry()
    void RefreshOnTeamCountry(bool playEffect = false)
    {
        Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType);
        Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType, true);
        var config = HeroLineupHaloConfig.GetConfig(result.x, result.y);
        if (config == null)
        {
            countryOnImg.SetSprite("heroTeamCountry" + result.x);
            countryOnImg.SetSprite("heroTeamCountry0");
            for (int i = 0; i < OnCountImgs.Count; i++)
            {
                OnCountImgs[i].SetActive(false);
@@ -152,6 +266,8 @@
                    OnCountImgs[i].SetActive(false);
                }
            }
            if (playEffect)
                countryEffect.Play();
        }
    }
@@ -181,7 +297,201 @@
    }
    void RefreshTeamHero()
    {
        var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType);
        for (int i = 0; i < sceneHero.Length; i++)
        {
            var teamHero = team.tempHeroes[i];
            if (teamHero == null)
            {
                sceneHero[i].SetActive(false);
            }
            else
            {
                sceneHero[i].SetActive(true);
                sceneHero[i].Display(teamHero.guid, i);
                //按scenePosImgs 顺序排序对应位置
                sceneHero[i].transform.position = scenePosImgs[i].transform.position;
                sceneHero[i].transform.localScale = Vector3.one;
            }
        }
        RefreshPosScale();
    }
    void RefreshPosScale()
    {
        for (int i = 0; i < scenePosImgs.Count; i++)
        {
            scenePosImgs[i].transform.localScale = Vector3.one;
        }
    }
    /// <summary>
    /// 点击上阵,拖拉,一键等触发;
    /// </summary>
    /// <param name="posList">要刷新的布阵位置</param>
    /// <param name="flyFrom">大于-1代表是点击上阵,需要表现飞行效果</param>
    void TeamChangeEvent(List<int> posList, int flyFrom, Vector3 startPos)
    {
        var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType);
        foreach (var i in posList)
        {
            var teamHero = team.tempHeroes[i];
            if (teamHero == null)
            {
                sceneHero[i].SetActive(false);
            }
            else
            {
                sceneHero[i].SetActive(true);
                sceneHero[i].Display(teamHero.guid, i, flyFrom >= 0, flyFrom != -2 ? true : false);
                //按scenePosImgs 顺序排序对应位置
                sceneHero[i].transform.position = scenePosImgs[i].transform.position;
                sceneHero[i].transform.localScale = Vector3.one;
            }
        }
        RefreshPosScale();
        heroListScroller.m_Scorller.RefreshActiveCellViews();
        RefreshOnTeamCountry(true);
        OnBattleTeamAttrPer();
        //表现飞入,连续点击不同头像触发的话则重置
        if (flyFrom > -1)
        {
            var flyHero = HeroManager.Instance.GetHero(HeroUIManager.Instance.heroOnTeamSortList[flyFrom]);
            if (flyHero == null)
                return;
            //先停止 sequence
            if (sequence != null)
            {
                sequence.Kill();
            }
            sequence = DOTween.Sequence();
            flyAlphaTween.alpha = 1;
            flyHead.Init(flyHero.heroId, flyHero.SkinID);
            flyHead.transform.position = startPos;
            var targetPos = scenePosImgs[posList[0]].transform.position;
            flyHead.transform.localScale = Vector3.one;
            sequence.Append(flyHead.transform.DOMove(targetPos, HeroUIManager.clickFlyPosTime).SetEase(Ease.OutQuad))
                .Join(flyHead.transform.DOScale(new Vector3(0.5f, 0.5f, 0.5f), HeroUIManager.clickFlyPosTime).SetEase(Ease.OutQuad))
                .Join(flyAlphaTween.DOFade(0f, HeroUIManager.clickFlyPosTime).SetEase(Ease.OutQuad));
            sequence.onComplete = () => { flyHead.transform.localScale = Vector3.zero; };
            if (isToggleOn)
            {
                ShowFetter(flyHero);
            }
        }
        fightPowerText.text = UIHelper.ReplaceLargeArtNum(FightPowerManager.Instance.GetTeamFightPower(HeroUIManager.Instance.selectTeamType, true));
    }
    void ShowFetter(HeroInfo hero)
    {
        var heroConfig = hero.heroConfig;
        var fetterList = hero.GetActiveFetter(heroConfig, TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType));
        for (int i = 0; i < fetterList.Count; i++)
        {
            if (!showConnectTipQueue.Contains(fetterList[i]))
                showConnectTipQueue.Enqueue(fetterList[i]);
        }
        if (_cts == null)
        {
            _cts = new CancellationTokenSource();
            RunTaskAsync(_cts.Token).Forget(); // Forget() 表示不等待此任务完成
        }
    }
    async UniTask RunTaskAsync(CancellationToken token)
    {
        try
        {
            while (showConnectTipQueue.Count > 0)
            {
                await UniTask.Delay(300, cancellationToken: token);
                showConnectTipQueue.TryDequeue(out int fetterID);
                if (fetterID == 0)
                {
                    continue;
                }
                connetionForm.SetActive(true);
                connetionForm.Display(fetterID);
                //显示1.5秒后关闭
                await UniTask.Delay(1500, cancellationToken: token);
                connetionForm.SetActive(false);
            }
        }
        catch (OperationCanceledException)
        {
            Debug.Log("羁绊 协程被取消");
            connetionForm.SetActive(false);
        }
        finally
        {
            _cts?.Dispose();     // 释放资源
            _cts = null;         // 置空避免重复取消
            showConnectTipQueue.Clear();
        }
    }
    // 取消当前正在运行的任务
    public void CancelCurrentTask()
    {
        _cts?.Cancel();      // 触发取消
        _cts?.Dispose();     // 释放资源
        _cts = null;         // 置空避免重复取消
        showConnectTipQueue.Clear();
    }
    void OneKeyOnPos()
    {
        var guidList = HeroUIManager.Instance.SelectRecommend();
        var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType);
        team.RemoveAllHeroes();
        for (int i = 0; i < guidList.Count; i++)
        {
            team.AddHero(HeroManager.Instance.GetHero(guidList[i]), i);
        }
        TeamChangeEvent(new List<int>() { 0, 1, 2, 3, 4, 5 }, -1, Vector3.zero);
    }
    void SaveTeam()
    {
        var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType);
        team.SaveTeam();
    }
    void SelectTeamFunc(TeamType type)
    {
        if (HeroUIManager.Instance.selectTeamType == type)
        {
            return;
        }
        HeroUIManager.Instance.selectTeamPosJob = 0;
        HeroUIManager.Instance.selectTeamPosCountry = 0;
        HeroUIManager.Instance.selectTeamType = type;
        HeroUIManager.Instance.SortHeroOnTeamList();
        Refresh();
        heroListScroller.m_Scorller.RefreshActiveCellViews();
    }
    protected void OnTeamChange(TeamType teamType)
    {
        if (HeroUIManager.Instance.selectTeamType == teamType)
        {
            HeroUIManager.Instance.SortHeroOnTeamList();
            heroListScroller.m_Scorller.RefreshActiveCellViews();
        }
    }
}