lcy
2025-10-28 b7bad9b52d93aec7fe16d2b086af927a44533dee
143 挑战按钮逻辑优化,方便后续接入
2个文件已修改
6个文件已添加
512 ■■■■ 已修改文件
Main/System/ChallengeTab/ArenaTabHandler.cs 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/ArenaTabHandler.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/BaseChallengeTabHandler.cs 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/BaseChallengeTabHandler.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/BoneFieldTabHandler.cs 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/BoneFieldTabHandler.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/ChallengeTabButton.cs 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/ChallengeTabWin.cs 140 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/ChallengeTab/ArenaTabHandler.cs
New file
@@ -0,0 +1,65 @@
using System;
using UnityEngine;
public class ArenaTabHandler : BaseChallengeTabHandler
{
    protected override int GetIndex() => 1;
    protected override int GetOpenState() => 0; // 0=FuncID
    protected override int GetFuncId() => ArenaManager.Instance.funcId;
    protected override int GetRedpointId() => MainRedDot.ArenaRepoint;
    protected override string GetCountInfo()
    {
        long nowCount = UIHelper.GetMoneyCnt(ArenaManager.Instance.ChallengeMoneyType);
        return UIHelper.AppendColor(nowCount > 0 ? TextColType.Green : TextColType.Red, Language.Get("Challenge03", nowCount));
    }
    protected override Action GetOnClickAction()
    {
        return HandleArenaNavigation;
    }
    private void HandleArenaNavigation()
    {
        if (!FuncOpen.Instance.IsFuncOpen(GetFuncId(), true))
            return;
        BattleField arenaBattle = BattleManager.Instance.GetBattleFieldByMapID(3);
        if (arenaBattle != null)
        {
            ArenaBattleWin battleWin;
            if (!UIManager.Instance.IsOpened<ArenaBattleWin>())
            {
                battleWin = UIManager.Instance.OpenWindow<ArenaBattleWin>();
            }
            else
            {
                battleWin = UIManager.Instance.GetUI<ArenaBattleWin>();
            }
            battleWin.SetBattleField(arenaBattle);
        }
        else
        {
            UIManager.Instance.OpenWindow<ArenaWin>();
        }
    }
    protected override void SubscribeToSpecificEvents()
    {
        PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefresh;
    }
    protected override void UnsubscribeFromSpecificEvents()
    {
        PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefresh;
    }
    private void OnPlayerDataRefresh(PlayerDataType type)
    {
        if (type == PlayerDataType.ChallengeVoucher)
        {
            Refresh();
        }
    }
}
Main/System/ChallengeTab/ArenaTabHandler.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e08213d7902819944bd303758458714a
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/ChallengeTab/BaseChallengeTabHandler.cs
New file
@@ -0,0 +1,108 @@
using System;
using UnityEngine;
/// <summary>
/// 挑战标签页按钮的逻辑处理基类
/// 挂在与 ChallengeTabButton 同一个GameObject上
/// </summary>
[RequireComponent(typeof(ChallengeTabButton))]
public abstract class BaseChallengeTabHandler : MonoBehaviour
{
    protected ChallengeTabButton tabButton;
    private ChallengeTabButton.DisplayData displayData;
    protected virtual void Awake()
    {
        tabButton = GetComponent<ChallengeTabButton>();
        // 初始化一次 DisplayData,之后只修改变化的字段
        displayData = new ChallengeTabButton.DisplayData
        {
            Index = GetIndex(),
            RedpointId = GetRedpointId(),
            OpenState = GetOpenState(),
            FuncId = GetFuncId(),
            OnClickAction = GetOnClickAction()
        };
    }
    /// <summary>
    /// 订阅事件 (由 ChallengeTabWin 在 OnPreOpen 时调用)
    /// </summary>
    public virtual void SubscribeEvents()
    {
        // 订阅全局刷新事件
        TimeMgr.Instance.OnDayEvent += Refresh;
        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChange;
        // 订阅此按钮特定的事件
        SubscribeToSpecificEvents();
    }
    /// <summary>
    /// 取消订阅事件 (由 ChallengeTabWin 在 OnPreClose 时调用)
    /// </summary>
    public virtual void UnsubscribeEvents()
    {
        TimeMgr.Instance.OnDayEvent -= Refresh;
        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChange;
        UnsubscribeFromSpecificEvents();
    }
    /// <summary>
    /// 刷新UI显示 (由 ChallengeTabWin 或事件回调调用)
    /// </summary>
    public void Refresh()
    {
        if (tabButton == null)
            return;
        displayData.CountInfo = GetCountInfo();
        tabButton.Display(displayData);
    }
    private void OnFuncStateChange(int funcId)
    {
        if (GetOpenState() == 0 && funcId == GetFuncId())
        {
            Refresh();
        }
    }
    /// <summary>
    /// 获取Tab的索引(用于Icon和Name)
    /// </summary>
    protected abstract int GetIndex();
    /// <summary>
    /// 获取开启方式 (0=FuncID, 1=活动)
    /// </summary>
    protected abstract int GetOpenState();
    /// <summary>
    /// 获取功能ID
    /// </summary>
    protected abstract int GetFuncId();
    /// <summary>
    /// 获取红点ID
    /// </summary>
    protected abstract int GetRedpointId();
    /// <summary>
    /// 获取数量的显示文本
    /// </summary>
    protected abstract string GetCountInfo();
    /// <summary>
    /// 获取按钮点击时触发的 *具体* 业务逻辑
    /// </summary>
    protected abstract Action GetOnClickAction();
    /// <summary>
    /// 订阅此Tab特有的事件
    /// </summary>
    protected abstract void SubscribeToSpecificEvents();
    /// <summary>
    /// 取消订阅此Tab特有的事件
    /// </summary>
    protected abstract void UnsubscribeFromSpecificEvents();
}
Main/System/ChallengeTab/BaseChallengeTabHandler.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 91477a81b5997714db36457077d03ac4
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/ChallengeTab/BoneFieldTabHandler.cs
New file
@@ -0,0 +1,78 @@
using System;
using UnityEngine;
public class BoneFieldTabHandler : BaseChallengeTabHandler
{
    protected override int GetIndex() => 2;
    protected override int GetOpenState() => 0; // 0=FuncID
    protected override int GetFuncId() => BoneFieldManager.Instance.funcId;
    protected override int GetRedpointId() => MainRedDot.BoneFieldRepoint;
    protected override string GetCountInfo()
    {
        if (BoneFieldManager.Instance.TryGetShowSweepCount(out int _, out int showrealRemainSweepCount))
        {
            return UIHelper.AppendColor(showrealRemainSweepCount > 0 ? TextColType.Green : TextColType.Red, Language.Get("Challenge01", showrealRemainSweepCount));
        }
        return string.Empty; // 获取失败时返回空
    }
    protected override Action GetOnClickAction()
    {
        return HandleBoneFieldNavigation;
    }
    private void HandleBoneFieldNavigation()
    {
        if (!FuncOpen.Instance.IsFuncOpen(GetFuncId(), true))
            return;
        BattleField battleField = BattleManager.Instance.GetBattleFieldByMapID(30010);
        if (battleField != null)
        {
            BoneFieldBattleWin battleWin;
            if (!UIManager.Instance.IsOpened<BoneFieldBattleWin>())
            {
                battleWin = UIManager.Instance.OpenWindow<BoneFieldBattleWin>();
            }
            else
            {
                battleWin = UIManager.Instance.GetUI<BoneFieldBattleWin>();
            }
            battleWin.SetBattleField(battleField as BoneBattleField);
        }
        else
        {
            UIManager.Instance.OpenWindow<BoneFieldWin>();
        }
    }
    protected override void SubscribeToSpecificEvents()
    {
        DungeonManager.Instance.UpdateFBInfoChangeEvent += OnUpdateFBInfoChange;
        AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdate;
    }
    protected override void UnsubscribeFromSpecificEvents()
    {
        DungeonManager.Instance.UpdateFBInfoChangeEvent -= OnUpdateFBInfoChange;
        AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdate;
    }
    private void OnUpdateFBInfoChange(int mapID, bool isADAddCntChange, bool isBuyAddCntChange, bool isItemAddCntChange)
    {
        if (mapID == BoneFieldManager.Instance.DataMapID)
        {
            Refresh();
        }
    }
    private void OnAdsInfoListUpdate(int adID, int mapID)
    {
        if (mapID == BoneFieldManager.Instance.DataMapID)
        {
            Refresh();
        }
    }
}
Main/System/ChallengeTab/BoneFieldTabHandler.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc6f3e382ad10c048af48f137e2f9569
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/ChallengeTab/ChallengeTabButton.cs
@@ -11,31 +11,73 @@
    [SerializeField] TextEx txtLockInfo;
    [SerializeField] Transform transUnlock;
    [SerializeField] RedpointBehaviour redpointBehaviour;
    Action action;
    void Awake()
    private Action _onClickAction;
    public struct DisplayData
    {
        btnTab.SetListener(() =>
        {
            UIManager.Instance.CloseWindow<ChallengeTabWin>();
            string activeBattleName = BattleManager.Instance.GetActiveBattleName();
            if (activeBattleName != "" && activeBattleName != "StoryBattleField")
            {
                UIManager.Instance.GetUI<MainWin>().ClickFunc(0);
            }
            action?.Invoke();
        });
        public int Index;
        public int RedpointId;
        public int OpenState;//0 FuncID 1 活动
        public int FuncId;
        public string CountInfo;
        public Action OnClickAction; // 按钮点击时触发的具体逻辑
    }
    public void Display(int index, int redpointId, bool isLock, string countInfo, string lockInfo, Action action)
    void Awake()
    {
        redpointBehaviour.redpointId = redpointId;
        transUnlock.SetActive(!isLock);
        txtCount.SetActive(isLock);
        txtLockInfo.SetActive(!isLock);
        imgIcon.SetSprite(StringUtility.Contact("ChallengeTab", index));
        txtName.text = Language.Get(StringUtility.Contact("ChallengeTab", index));
        txtCount.text = countInfo;
        txtLockInfo.text = lockInfo;
        this.action = action;
        btnTab.SetListener(OnTabClicked);
    }
}
    /// <summary>
    /// 处理按钮点击事件
    /// </summary>
    private void OnTabClicked()
    {
        // --- 通用点击逻辑 ---
        UIManager.Instance.CloseWindow<ChallengeTabWin>();
        string activeBattleName = BattleManager.Instance.GetActiveBattleName();
        if (activeBattleName != "" && activeBattleName != "StoryBattleField")
        {
            UIManager.Instance.GetUI<MainWin>().ClickFunc(0);
        }
        // 执行传入的具体业务逻辑
        _onClickAction?.Invoke();
    }
    /// <summary>
    /// 使用 DisplayData 结构体来更新按钮显示
    /// </summary>
    /// <param name="data">包含所有显示和行为配置的数据</param>
    public void Display(DisplayData data)
    {
        redpointBehaviour.redpointId = data.RedpointId;
        bool isOpen;
        if (data.OpenState == 0)
        {
            isOpen = FuncOpen.Instance.IsFuncOpen(data.FuncId);
        }
        else
        {
            isOpen = false;
        }
        // 根据锁定状态设置显隐
        transUnlock.SetActive(!isOpen);
        txtCount.SetActive(isOpen);
        txtLockInfo.SetActive(!isOpen);
        // 设置图标和名称
        string spriteAndLangKey = StringUtility.Contact("ChallengeTab", data.Index);
        imgIcon.SetSprite(spriteAndLangKey);
        txtName.text = Language.Get(spriteAndLangKey);
        // 设置TIPS文本
        txtCount.text = data.CountInfo;
        txtLockInfo.text = !isOpen ? Language.Get("Challenge02") : string.Empty;
        // 存储点击回调
        this._onClickAction = data.OnClickAction;
    }
}
Main/System/ChallengeTab/ChallengeTabWin.cs
@@ -3,146 +3,42 @@
public class ChallengeTabWin : UIBase
{
    [SerializeField] ChallengeTabButton btnBoneField;
    [SerializeField] ChallengeTabButton btnArena;
    private BaseChallengeTabHandler[] tabHandlers;
    protected override void InitComponent()
    {
        base.InitComponent();
        // 自动查找所有子对象上的 Handler 组件
        tabHandlers = GetComponentsInChildren<BaseChallengeTabHandler>(true);
    }
    protected override void OnPreOpen()
    {
        base.OnPreOpen();
        DungeonManager.Instance.UpdateFBInfoChangeEvent += OnUpdateFBInfoChangeEvent;
        AdsManager.Instance.OnAdsInfoListUpdateEvent += OnAdsInfoListUpdateEvent;
        TimeMgr.Instance.OnDayEvent += OnDayEvent;
        FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent;
        PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefresh;
        foreach (var handler in tabHandlers)
        {
            handler.SubscribeEvents();
        }
        Display();
    }
    protected override void OnPreClose()
    {
        base.OnPreClose();
        DungeonManager.Instance.UpdateFBInfoChangeEvent -= OnUpdateFBInfoChangeEvent;
        AdsManager.Instance.OnAdsInfoListUpdateEvent -= OnAdsInfoListUpdateEvent;
        TimeMgr.Instance.OnDayEvent -= OnDayEvent;
        FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent;
        PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefresh;
        foreach (var handler in tabHandlers)
        {
            handler.UnsubscribeEvents();
        }
        UIManager.Instance.GetUI<MainWin>()?.RestoreFuncBtn();
    }
    private void OnDayEvent()
    {
        Display();
    }
    private void OnAdsInfoListUpdateEvent(int id, int mapId)
    {
        Display();
    }
    private void OnUpdateFBInfoChangeEvent(int arg1, bool arg2, bool arg3, bool arg4)
    {
        if (arg1 == BoneFieldManager.Instance.DataMapID)
        {
            DisplayBoneFieldButton();
        }
    }
    public void OnFuncStateChangeEvent(int funcId)
    {
        if (funcId == BoneFieldManager.Instance.funcId)
        {
            DisplayBoneFieldButton();
        }
        else if (funcId == ArenaManager.Instance.funcId)
        {
            DisplayArenaButton();
        }
    }
    private void PlayerDataRefresh(PlayerDataType type)
    {
        if (type == PlayerDataType.ChallengeVoucher)
        {
            DisplayArenaButton();
        }
    }
    public void Display()
    {
        DisplayBoneFieldButton();
        DisplayArenaButton();
    }
    public void DisplayArenaButton()
    {
        int index = 1;
        int funcId = ArenaManager.Instance.funcId;
        int redpointId = MainRedDot.ArenaRepoint;
        bool isLock = FuncOpen.Instance.IsFuncOpen(funcId);
        int type = ArenaManager.Instance.ChallengeMoneyType;
        long nowCount = UIHelper.GetMoneyCnt(type);
        string countInfo = UIHelper.AppendColor(nowCount > 0 ? TextColType.Green : TextColType.Red, Language.Get("Challenge03", nowCount));
        string lockInfo = !isLock ? Language.Get("Challenge02") : string.Empty;
        btnArena.Display(index, redpointId, isLock, countInfo, lockInfo, () =>
        {
            if (!FuncOpen.Instance.IsFuncOpen(funcId, true))
                return;
            BattleField arenaBattle = BattleManager.Instance.GetBattleFieldByMapID(3);
            if (arenaBattle != null)
            {
                ArenaBattleWin battleWin;
                if (!UIManager.Instance.IsOpened<ArenaBattleWin>())
                {
                    battleWin = UIManager.Instance.OpenWindow<ArenaBattleWin>();
                }
                else
                {
                    battleWin = UIManager.Instance.GetUI<ArenaBattleWin>();
                }
                battleWin.SetBattleField(arenaBattle);
            }
            else
            {
                UIManager.Instance.OpenWindow<ArenaWin>();
            }
        });
    }
    public void DisplayBoneFieldButton()
    {
        int index = 2;
        int funcId = BoneFieldManager.Instance.funcId;
        int redpointId = MainRedDot.BoneFieldRepoint;
        bool isLock = FuncOpen.Instance.IsFuncOpen(funcId);
        if (!BoneFieldManager.Instance.TryGetShowSweepCount(out int showSweepMaxCount, out int showrealRemainSweepCount))
        if (tabHandlers == null)
            return;
        string countInfo = UIHelper.AppendColor(showrealRemainSweepCount > 0 ? TextColType.Green : TextColType.Red, Language.Get("Challenge01", showrealRemainSweepCount));
        string lockInfo = !isLock ? Language.Get("Challenge02") : string.Empty;
        btnBoneField.Display(index, redpointId, isLock, countInfo, lockInfo, () =>
        foreach (var handler in tabHandlers)
        {
            if (!FuncOpen.Instance.IsFuncOpen(funcId, true))
                return;
            BattleField battleField = BattleManager.Instance.GetBattleFieldByMapID(30010);
            if (battleField != null)
            {
                BoneFieldBattleWin battleWin;
                if (!UIManager.Instance.IsOpened<BoneFieldBattleWin>())
                {
                    battleWin = UIManager.Instance.OpenWindow<BoneFieldBattleWin>();
                }
                else
                {
                    battleWin = UIManager.Instance.GetUI<BoneFieldBattleWin>();
                }
                battleWin.SetBattleField(battleField as BoneBattleField);
            }
            else
            {
                UIManager.Instance.OpenWindow<BoneFieldWin>();
            }
        });
            handler.Refresh();
        }
    }
}
}