hch
2025-09-10 53ce447affac8557a2c0570875d41f45590372d4
117 【武将】武将系统 - 满级预览
4个文件已修改
2个文件已添加
524 ■■■■■ 已修改文件
Main/System/HeroUI/HeroBestWin.cs 480 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroBestWin.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroCollectionCardCell.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroTrainWin.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.Collect.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroUIManager.cs 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/HeroUI/HeroBestWin.cs
New file
@@ -0,0 +1,480 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 武将满级预览界面
/// </summary>
public class HeroBestWin : UIBase
{
    [SerializeField] RawImage bgTexture;
    [SerializeField] Button showFuncBtn;    //只显示立绘时点击,显示功能
    [SerializeField] Transform funcForm;
    [SerializeField] UIHeroController roleLhModel;    //展示英雄立绘
    [SerializeField] Button rightBtn;
    [SerializeField] Button leftBtn;
    [SerializeField] UIHeroController roleXsModel;  //像素
    [SerializeField] Image jobImg;
    [SerializeField] Text jobPosNameText;
    [SerializeField] Text descText;
    [SerializeField] HeroConnectionCell connetionForm;  //羁绊
    [SerializeField] Button seeLhBtn;   //查看立绘
    [SerializeField] SkillBaseCell normalSkillCell;
    [SerializeField] SkillBaseCell angerSkillCell;
    [SerializeField] Button closeBtn;   //关闭按钮
    [SerializeField] Button starBtn;   //显示星级文字
    [SerializeField] List<Image> starImgList;
    [SerializeField] Text nameText;
    [SerializeField] UIEffectPlayer nameEffect;
    [SerializeField] Image countryImg;
    [SerializeField] Text awakeLVText;
    //属性区
    [SerializeField] ScrollRect allAttrScroll;
    [SerializeField] Button attrBtn;
    [SerializeField] Image unfoldImg; //展开时按钮的图标
    [SerializeField] Image foldImg; //收起时按钮的图标
    bool unfoldState = false;//是否展开
    [SerializeField] Transform foldPos;
    [SerializeField] Transform unfoldPos;   //展开时的位置
    [SerializeField] RectTransform attrPanel;  //显示的属性栏
    [SerializeField] RichText inheritText;   //武将继承描述
    [SerializeField] Text[] inheritAttrText;    //武将会继承的属性
    [SerializeField] RichText heroAddPerText; //主公(上阵)加成描述
    [SerializeField] Text[] heroAddAttrPerText; //主公(上阵)加成
    [SerializeField] GameObject potentialCell; //潜能和觉醒用于创建
    [SerializeField] Transform potentialCellParent; //潜能父节点
    List<GameObject> potentialCellList;   //潜能
    [SerializeField] Transform awakeCellParent; //潜能父节点
    [SerializeField] GameObject awakeGo;
    List<GameObject> awakeCellList;   //觉醒
    [SerializeField] GameObject fetterGo;
    [SerializeField] Text[] fetterText;   //羁绊
    [SerializeField] Text[] fetterNameText;   //羁绊
    //天赋
    [SerializeField] GiftBaseCell[] giftBaseCells;
    HeroConfig heroConfig;
    int heroLevel;
    int heroStar;
    int breakLevel;
    int awakeLevel;
    protected override void InitComponent()
    {
        showFuncBtn.AddListener(() =>
        {
            funcForm.SetActive(true);
        });
        seeLhBtn.AddListener(() =>
        {
            funcForm.SetActive(false);
        });
        closeBtn.AddListener(CloseWindow);
        rightBtn.AddListener(() =>
        {
            ChangeHero(1);
        });
        leftBtn.AddListener(() =>
        {
            ChangeHero(-1);
        });
        inheritText.OnClick = () =>
        {
            SmallTipWin.showText = Language.Get("herocard47");
            SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
            UIManager.Instance.OpenWindow<SmallTipWin>();
        };
        heroAddPerText.OnClick = () =>
        {
            SmallTipWin.showText = Language.Get("herocard48");
            SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
            UIManager.Instance.OpenWindow<SmallTipWin>();
        };
        attrBtn.AddListener(() =>
        {
            unfoldState = !unfoldState;
            RefreshFoldState();
        });
        starBtn.AddListener(() =>
        {
            var config = HeroConfig.Get(HeroUIManager.Instance.selectForPreviewHeroID);
            SmallTipWin.showText = Language.Get("HeroGift14",
            HeroUIManager.Instance.GetMaxStarCount(HeroUIManager.Instance.selectForPreviewHeroID, config.Quality));
            SmallTipWin.worldPos = CameraManager.uiCamera.ScreenToWorldPoint(Input.mousePosition);
            UIManager.Instance.OpenWindow<SmallTipWin>();
        });
        potentialCellList = new List<GameObject>();
        awakeCellList = new List<GameObject>();
    }
    protected override void OnPreOpen()
    {
        unfoldState = false;
        allAttrScroll.verticalNormalizedPosition = 1;
        Display();
    }
    public void Display()
    {
        heroConfig = HeroConfig.Get(HeroUIManager.Instance.selectForPreviewHeroID);
        bgTexture.SetTexture2D("countryBG" + heroConfig.Country);
        int skinID = heroConfig.SkinIDList[0];
        roleLhModel.Create(skinID, 1, motionName: "", isLh: true);
        roleXsModel.Create(skinID);
        jobImg.SetSprite(HeroUIManager.Instance.GetJobIconName(heroConfig.Class));
        jobPosNameText.text = HeroUIManager.Instance.GetJobName(heroConfig.Class);
        descText.text = heroConfig.Desc;
        RefreshConn();
        normalSkillCell.Init(heroConfig.AtkSkillID, () =>
        {
            UIManager.Instance.OpenWindow<HeroSkillWin>(HeroUIManager.Instance.selectForPreviewHeroID);
        }, true);
        angerSkillCell.Init(heroConfig.AngerSkillID, () =>
        {
            UIManager.Instance.OpenWindow<HeroSkillWin>(HeroUIManager.Instance.selectForPreviewHeroID);
        }, true);
        RefreshName();
        RefreshFoldState();
        RefreshAttr();
        RefreshAllPotential();
        RefreshFetter();
        RefreshGift();
        RefreshAwake();
    }
    void RefreshConn()
    {
        if (heroConfig.FetterIDList.Length > 0)
        {
            connetionForm.SetActive(true);
            connetionForm.Display(heroConfig.FetterIDList[0], Language.Get("herocard38") + "\n", true);
        }
        else
        {
            connetionForm.SetActive(false);
        }
    }
    void ChangeHero(int changeValue)
    {
        var index = HeroUIManager.Instance.heroCollectList.IndexOf(HeroUIManager.Instance.selectForPreviewHeroID);
        if (index == -1)
            return;
        allAttrScroll.verticalNormalizedPosition = 1;
        int resultIndex = index + changeValue;
        //循环处理
        if (resultIndex < 0)
        {
            resultIndex = HeroUIManager.Instance.heroCollectList.Count - 1;
        }
        else if (resultIndex > HeroUIManager.Instance.heroCollectList.Count - 1)
        {
            resultIndex = 0;
        }
        HeroUIManager.Instance.selectForPreviewHeroID = HeroUIManager.Instance.heroCollectList[resultIndex];
        Display();
    }
    void RefreshStars()
    {
        heroStar = HeroUIManager.Instance.GetMaxStarCount(HeroUIManager.Instance.selectForPreviewHeroID, heroConfig.Quality);
        for (int i = 0; i < starImgList.Count; i++)
        {
            if ((heroStar - 1) % starImgList.Count >= i)
            {
                starImgList[i].SetActive(true);
                starImgList[i].SetSprite("herostar" + (((heroStar - 1) / starImgList.Count) + 1) * starImgList.Count);
            }
            else
            {
                starImgList[i].SetActive(false);
            }
        }
    }
    void RefreshName()
    {
        RefreshStars();
        breakLevel = HeroBreakConfig.GetMaxBreakLv(HeroUIManager.Instance.selectForPreviewHeroID);
        nameText.text = breakLevel == 0 ? heroConfig.Name : Language.Get("herocardbreaklv", heroConfig.Name, breakLevel);
        nameText.color = UIHelper.GetUIColorByFunc(heroConfig.Quality);
        if (heroConfig.Quality >= 4)
        {
            nameEffect.SetActive(true);
            nameEffect.Play(heroConfig.Quality == 4 ? 0 : 1);
        }
        else
        {
            nameEffect.SetActive(false);
        }
        countryImg.SetSprite(HeroUIManager.Instance.GetCountryIconName(heroConfig.Country));
        awakeLevel = HeroAwakeConfig.GetMaxAwakeLV(HeroUIManager.Instance.selectForPreviewHeroID);
        heroLevel = HeroUIManager.Instance.GetMaxLVByBreakLV(heroConfig.Quality, breakLevel);
        if (awakeLevel == 0)
        {
            awakeLVText.text = Language.Get("L1094") + heroLevel;
            awakeLVText.GetComponent<OutlineEx>().colorType = QualityTextColType.itemcucao;
        }
        else
        {
            awakeLVText.text = Language.Get("L1094") + heroLevel + " " + Language.Get("herocard12", awakeLevel);
            awakeLVText.GetComponent<OutlineEx>().colorType = QualityTextColType.red;
        }
    }
    void RefreshFoldState()
    {
        if (!unfoldState)
        {
            foldImg.SetActive(true);
            unfoldImg.SetActive(false);
            attrPanel.localPosition = foldPos.localPosition;
            //禁止attrScroll滚动
            allAttrScroll.enabled = false;
        }
        else
        {
            foldImg.SetActive(false);
            unfoldImg.SetActive(true);
            attrPanel.localPosition = unfoldPos.localPosition;
            allAttrScroll.enabled = true;
        }
    }
    public int GetOnBattleAddPer()
    {
        var qualityConfig = HeroQualityConfig.Get(heroConfig.Quality);
        return qualityConfig.InitAddPer + qualityConfig.LVAddPer * (heroLevel - 1) + qualityConfig.BreakLVAddPer * breakLevel + qualityConfig.StarAddPer * heroStar;
    }
    void RefreshAttr()
    {
        inheritAttrText[0].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.inheritAttrs[0], heroConfig.AtkInheritPer));
        inheritAttrText[1].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.inheritAttrs[1], heroConfig.DefInheritPer));
        inheritAttrText[2].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.inheritAttrs[2], heroConfig.HPInheritPer));
        //上阵属性
        int valuePer = GetOnBattleAddPer();
        for (int i = 0; i < heroAddAttrPerText.Length; i++)
        {
            heroAddAttrPerText[i].text = PlayerPropertyConfig.GetFullDescription(new Int2(PlayerPropertyConfig.basePerAttrs[i], valuePer));
        }
    }
    void RefreshAllPotential()
    {
        if (!HeroBreakConfig.configDics.ContainsKey(HeroUIManager.Instance.selectForPreviewHeroID))
            return;
        var list = HeroBreakConfig.configDics[HeroUIManager.Instance.selectForPreviewHeroID].Keys.ToList();
        list.Sort();
        for (int i = 0; i < list.Count; i++)
        {
            var nextQualityBreakConfig = HeroBreakConfig.GetHeroBreakConfig(HeroUIManager.Instance.selectForPreviewHeroID, i + 1);
            if (nextQualityBreakConfig == null)
                break;
            List<string> attrStrArr = new List<string>();
            for (int j = 0; j < nextQualityBreakConfig.AttrIDList.Length; j++)
            {
                if (nextQualityBreakConfig.AttrIDList[j] == 0)
                    continue;
                string format = i < breakLevel ? "{0}" + UIHelper.AppendColor(TextColType.Green, "+{1}") : "{0}+{1}";
                attrStrArr.Add(PlayerPropertyConfig.GetFullDescription(nextQualityBreakConfig.AttrIDList[j], nextQualityBreakConfig.AttrValueList[j], format));
            }
            if (nextQualityBreakConfig.SkillID != 0)
            {
                var skill = SkillConfig.Get(nextQualityBreakConfig.SkillID);
                if (skill != null)
                {
                    attrStrArr.Add(Language.Get("equipQualityFormat", skill.SkillName) + skill.Description);
                }
                else
                {
                    Debug.LogError("未配置技能" + nextQualityBreakConfig.SkillID);
                }
            }
            if (i >= potentialCellList.Count)
            {
                potentialCellList.Add(Instantiate(potentialCell, potentialCellParent));
            }
            var go = potentialCellList[i];
            var descText = go.GetComponent<Text>();
            var nameText = go.GetComponent<Text>("skillname");
            go.SetActive(true);
            if (i < breakLevel)
            {
                nameText.text = Language.Get("herocard63", i + 1);
                descText.text = string.Join(Language.Get("L1112"), attrStrArr);
            }
            else
            {
                //置灰
                nameText.text = UIHelper.AppendColor(TextColType.NavyGray, Language.Get("herocard63", i + 1));
                descText.text = UIHelper.AppendColor(TextColType.NavyGray, UIHelper.RemoveColor(string.Join(Language.Get("L1112"), attrStrArr)));
            }
        }
    }
    //羁绊
    void RefreshFetter()
    {
        if (heroConfig.FetterIDList.Length == 0)
        {
            fetterGo.SetActive(false);
            return;
        }
        fetterGo.SetActive(true);
        for (int i = 0; i < fetterText.Length; i++)
        {
            if (i < heroConfig.FetterIDList.Length)
            {
                fetterText[i].SetActive(true);
                var fetterID = heroConfig.FetterIDList[i];
                HeroFetterConfig fetterConfig = HeroFetterConfig.Get(fetterID);
                List<string> heroNames = new List<string>();
                bool isAllCollect = true; //是否全收集
                foreach (var tmpHeroID in fetterConfig.HeroIDList)
                {
                    heroNames.Add(HeroConfig.Get(tmpHeroID).Name);
                    if (HeroManager.Instance.GetHeroCountByID(tmpHeroID) == 0)
                    {
                        isAllCollect = false;
                    }
                }
                var attrStr = string.Join(Language.Get("SplitString1"), heroNames) + Language.Get("herocard38");
                for (int j = 0; j < fetterConfig.AttrIDList.Length; j++)
                {
                    string format = !isAllCollect ? "{0}+{1}" : "{0}+" + UIHelper.AppendColor(TextColType.Green, "{1}");
                    attrStr += Language.Get("L1112") + PlayerPropertyConfig.GetFullDescription(fetterConfig.AttrIDList[j], fetterConfig.AttrValueList[j], format);
                }
                fetterText[i].text = attrStr;
                fetterText[i].color = UIHelper.GetUIColor(isAllCollect ? TextColType.NavyBrown : TextColType.NavyGray);
                fetterNameText[i].text = fetterConfig.FetterName;
                fetterNameText[i].color = UIHelper.GetUIColor(isAllCollect ? TextColType.NavyBrown : TextColType.NavyGray);
            }
            else
            {
                fetterText[i].SetActive(false);
            }
        }
    }
    void RefreshGift()
    {
        //最强显示
        for (int i = 0; i < giftBaseCells.Length; i++)
        {
            if (i < heroConfig.TalentList.Length)
            {
                giftBaseCells[i].SetActive(true);
                giftBaseCells[i].Init(heroConfig.TalentList[i], HeroUIManager.Instance.maxGiftLevel);
            }
            else
            {
                giftBaseCells[i].SetActive(false);
            }
        }
    }
    void RefreshAwake()
    {
        if (!HeroAwakeConfig.CanAwake(HeroUIManager.Instance.selectForPreviewHeroID, 1))
        {
            awakeGo.SetActive(false);
            return;
        }
        awakeGo.SetActive(true);
        var maxLV = HeroAwakeConfig.GetMaxAwakeLV(HeroUIManager.Instance.selectForPreviewHeroID);
        var starCnt = HeroQualityConfig.Get(heroConfig.Quality).InitStarUpper;
        for (int i = 1; i <= maxLV; i++)
        {
            if (i > awakeCellList.Count)
            {
                awakeCellList.Add(Instantiate(potentialCell, awakeCellParent));
            }
            var go = awakeCellList[i - 1];
            var descText = go.GetComponent<Text>();
            var nameText = go.GetComponent<Text>("skillname");
            go.SetActive(true);
            var config = HeroAwakeConfig.GetHeroAwakeConfig(HeroUIManager.Instance.selectForPreviewHeroID, i);
            int type = config.UnlockTalentSlot != 0 ? 1 : config.SkillID != 0 ? 2 : 3;
            var awakeStr = string.Empty;
            if (type == 1)
            {
                starCnt += config.AddStarUpper;
                awakeStr = Language.Get("HeroAwake8", config.UnlockTalentSlot, starCnt);
            }
            else if (type == 2)
            {
                var skill = SkillConfig.Get(config.SkillID);
                awakeStr = Language.Get("equipQualityFormat", skill.SkillName) + skill.Description;
            }
            else
            {
                for (int k = 0; k < config.AttrIDList.Length; k++)
                {
                    awakeStr += PlayerPropertyConfig.GetFullDescription(config.AttrIDList[k], config.AttrValueList[k], "{0}+" + UIHelper.AppendColor(TextColType.Green, "{1}"))
                    + (k == config.AttrIDList.Length - 1 ? "" : "\n");
                }
            }
            if (i - 1 < awakeLevel)
            {
                nameText.text = Language.Get("herocard12", i) + Language.Get("L1096");
                descText.text = awakeStr;
            }
            else
            {
                //置灰
                nameText.text = UIHelper.AppendColor(TextColType.NavyGray, Language.Get("herocard12", i) + Language.Get("L1096"));
                descText.text = UIHelper.AppendColor(TextColType.NavyGray, UIHelper.RemoveColor(awakeStr));
            }
        }
    }
}
Main/System/HeroUI/HeroBestWin.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e8eaaab6c9500944aafb7653793ed768
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/HeroUI/HeroCollectionCardCell.cs
@@ -76,6 +76,11 @@
            {
                UIManager.Instance.OpenWindow<HeroCollectionLvUpWin>();
            }
            else
            {
                HeroUIManager.Instance.selectForPreviewHeroID = heroID;
                UIManager.Instance.OpenWindow<HeroBestWin>();
            }
        });
        
        bookLVBtn.AddListener(() =>
Main/System/HeroUI/HeroTrainWin.cs
@@ -221,7 +221,6 @@
        PlayerMainDate.Instance.AddPowerNotOnTeam(hero);
        lockImg.SetActive(hero.isLock);
        unLockImg.SetActive(!hero.isLock);
        nameText.text = hero.breakLevel == 0 ? hero.heroConfig.Name : Language.Get("herocardbreaklv", hero.heroConfig.Name, hero.breakLevel);
        RefreshConn();
        normalSkillCell.Init(hero.heroConfig.AtkSkillID, () =>
@@ -334,6 +333,7 @@
    {
        RefreshStars();
        nameText.text = hero.breakLevel == 0 ? hero.heroConfig.Name : Language.Get("herocardbreaklv", hero.heroConfig.Name, hero.breakLevel);
        nameText.color = UIHelper.GetUIColorByFunc(hero.Quality);
        if (hero.Quality >= 4)
Main/System/HeroUI/HeroUIManager.Collect.cs
@@ -11,13 +11,15 @@
    public Dictionary<int, List<int>> heroCollectDict { get; private set; } = new Dictionary<int, List<int>>();  //武将图鉴按品质列表
    public List<int> heroCollectList = new List<int>(); //武将图鉴列表
    public int selectHeroCollectListJob = 0;    //武将列表界面 筛选职业
    public int selectHeroCollectListCountry = 0;    //武将列表界面筛选国家
    public int selectCollectHeroID; //选中的武将id
    public int selectCollectHeroID; //选中的武将id 用于升级
    public int bookMoneyType; //图鉴奖励货币类型
    public int bookMoneyValue;//图鉴奖励货币数量
    public int selectForPreviewHeroID; //选中的武将id 用于预览
    //图鉴和皮肤的激活情况
    Dictionary<int, HB122_tagSCHeroInfo.tagSCHero> heroCollectInfoDic = new Dictionary<int, HB122_tagSCHeroInfo.tagSCHero>();
@@ -87,6 +89,15 @@
            heroCollectDict[heroConfig.Quality].Add(heroID);
        }
        heroCollectList.Clear();
        //按品质倒序加入
        var _list = heroCollectDict.Keys.ToList();
        _list.Reverse();
        foreach (var quality in _list)
        {
            heroCollectList.AddRange(heroCollectDict[quality]);
        }
    }
    //图鉴总上限等级 = 图鉴星级上限 + 图鉴突破上限
Main/System/HeroUI/HeroUIManager.cs
@@ -142,10 +142,19 @@
        return hero.heroLevel >= GetMaxLV(hero.Quality);
    }
    //突破限制的最高等级
    //突破限制的最高等级; 存在突破等级可能更多的情况,不一定提供等级上限
    public int GetMaxLVByBreakLV(int quality, int breakLevel)
    {
        return HeroQualityBreakConfig.GetQualityBreakConfig(quality, breakLevel).LVMax;
        for (int i = breakLevel; i >= 0; i--)
        {
            var config = HeroQualityBreakConfig.GetQualityBreakConfig(quality, i);
            if (config == null)
            {
                continue;
            }
            return config.LVMax;
        }
        return 0;
    }
    public bool IsLVMaxByBreakLevel(HeroInfo hero)