hch
2025-08-31 74f26f60deac8fc1bb1f93ad26412f9a7e4a281d
50 【主界面】核心主体 - 战斗按钮逻辑
6个文件已修改
2个文件已添加
440 ■■■■■ 已修改文件
Main/Component/UI/Decorate/Tweens/FillTween.cs 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Decorate/Tweens/FillTween.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/StoryBattleField.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleManager.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Skill/SkillBase.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/AutoFightModel.cs 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Main/MainWin.cs 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Team/TeamBase.cs 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Decorate/Tweens/FillTween.cs
New file
@@ -0,0 +1,227 @@
//--------------------------------------------------------
//    [Author]:           玩个游戏
//    [  Date ]:           Thursday, September 14, 2017
//--------------------------------------------------------
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;
public class FillTween : MonoBehaviour
{
    public TweenCurve curve;
    [Range(0, 1)]
    public float from;
    [Range(0, 1)]
    public float to;
    public float delay = 0f;
    public float duration = 1f;
    public Trigger trigger = Trigger.Manual;
    public WrapMode wrapMode;
    public bool reversal;
    Image m_Image;
    public Image image {
        get {
            return m_Image ?? (m_Image = this.GetComponent<Image>());
        }
    }
    protected float accumulatedTime;
    protected float curveLength;
    protected bool doTween = false;
    Action onPlayEndCallBack;
    public void SetStartState()
    {
        image.fillAmount = from;
    }
    public void SetEndState()
    {
        image.fillAmount = to;
    }
    public void Play()
    {
        onPlayEndCallBack = null;
        reversal = false;
        StopAllCoroutines();
        if (this.gameObject.activeInHierarchy)
        {
            SetStartState();
            StartCoroutine("Co_StartTween");
        }
    }
    public void Play(bool _reversal)
    {
        onPlayEndCallBack = null;
        reversal = _reversal;
        StopAllCoroutines();
        if (this.gameObject.activeInHierarchy)
        {
            if (_reversal)
            {
                SetEndState();
            }
            else
            {
                SetStartState();
            }
            StartCoroutine("Co_StartTween");
        }
    }
    public void Play(Action _callBack)
    {
        onPlayEndCallBack = _callBack;
        reversal = false;
        StopAllCoroutines();
        if (this.gameObject.activeInHierarchy)
        {
            SetStartState();
            StartCoroutine("Co_StartTween");
        }
    }
    public void Stop()
    {
        doTween = false;
        accumulatedTime = 0f;
        StopAllCoroutines();
        SetStartState();
    }
    void Start()
    {
        if (trigger == Trigger.Start)
        {
            SetStartState();
            StartCoroutine("Co_StartTween");
        }
    }
    protected virtual void OnEnable()
    {
        if (trigger == Trigger.Enable)
        {
            SetStartState();
            StartCoroutine("Co_StartTween");
        }
    }
    protected virtual void OnDisable()
    {
        doTween = false;
        accumulatedTime = 0f;
        StopAllCoroutines();
    }
    void LateUpdate()
    {
        if (doTween && duration > 0.001f)
        {
            accumulatedTime += Time.deltaTime;
            UpdateFill();
        }
    }
    IEnumerator Co_StartTween()
    {
        if (delay < 0f)
        {
            Debug.LogError("Delaytime should not be less than zero!");
            yield break;
        }
        if (duration < 0.001f)
        {
            Debug.LogError("Duration should not be less than zero!");
            yield break;
        }
        if (curve.keys.Length < 2)
        {
            Debug.LogError("不正确的曲线!");
            yield break;
        }
        doTween = false;
        OnPrepare();
        yield return new WaitForSeconds(delay);
        curveLength = curve.keys[curve.keys.Length - 1].time - curve.keys[0].time;
        doTween = true;
        accumulatedTime = 0f;
    }
    protected void UpdateFill()
    {
        float t = 0f;
        switch (wrapMode)
        {
            case WrapMode.Once:
                t = (accumulatedTime / duration) * curveLength;
                break;
            case WrapMode.Loop:
                t = Mathf.Repeat((accumulatedTime / duration) * curveLength, 1);
                break;
            case WrapMode.PingPong:
                t = Mathf.PingPong((accumulatedTime / duration) * curveLength, 1);
                break;
        }
        var value = curve.Evaluate(reversal ? curveLength - t : t);
        image.fillAmount = Mathf.LerpUnclamped(from, to, value);
        switch (wrapMode)
        {
            case WrapMode.Once:
                if (t > curveLength && doTween)
                {
                    OnOnceEnd();
                    doTween = false;
                }
                break;
        }
    }
    protected virtual void OnPrepare()
    {
    }
    protected virtual void OnOnceEnd()
    {
        if (onPlayEndCallBack != null)
        {
            onPlayEndCallBack();
            onPlayEndCallBack = null;
        }
    }
    protected virtual void UpdateVector3()
    {
    }
    public enum Trigger
    {
        Manual,
        Start,
        Enable,
    }
    public enum WrapMode
    {
        Once,
        Loop,
        PingPong,
    }
}
Main/Component/UI/Decorate/Tweens/FillTween.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 47996afe725479248881d409acb960ac
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Battle/BattleField/StoryBattleField.cs
@@ -244,9 +244,10 @@
                }
            }
        }
        // else
        // {
        //     BattleDebug.LogError("action doesnt finish, wait a moment please");
        // }
        else
        {
            if (!AutoFightModel.Instance.isAutoAttack)
                BattleDebug.LogError("action doesnt finish, wait a moment please");
        }
    }
}
Main/System/Battle/BattleManager.cs
@@ -350,13 +350,13 @@
        if (isCreate)
        { 
            battleField = BattleFieldFactory.CreateBattleField(guid, MapID, FuncLineID, extendData, redTeamList, blueTeamList);
            onBattleFieldCreate?.Invoke(guid, battleField);
            if (string.IsNullOrEmpty(guid))
            {
                storyBattleField = (StoryBattleField)battleField;
            }
            battleFields.Add(guid, battleField);
            onBattleFieldCreate?.Invoke(guid, battleField);
        }
Main/System/Battle/Skill/SkillBase.cs
@@ -93,7 +93,7 @@
    // 1·移动到距离阵容位置n码的距离(如2号位,5号位)释放(即战场中央此类)
    public virtual void Cast()
    {
        EventBroadcast.Instance.Broadcast<string, SkillConfig>(EventName.BATTLE_CAST_SKILL, battleField.guid, skillConfig);
        EventBroadcast.Instance.Broadcast<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, battleField.guid, skillConfig, caster.teamHero);
        BattleDebug.LogError(GetType().Name + " Skill Cast Start");
        //    高亮所有本次技能相关的目标
Main/System/Main/AutoFightModel.cs
@@ -76,7 +76,9 @@
    {
        ParseConfig();
        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += BeforePlayerInit;
        BattleManager.Instance.onBattleFieldCreate += OnCreateBattleField;
        EventBroadcast.Instance.AddListener<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, OnSkillCast);
    }
@@ -84,6 +86,7 @@
    {
        DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk;
        BattleManager.Instance.onBattleFieldCreate -= OnCreateBattleField;
        DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= BeforePlayerInit;
    }
@@ -99,6 +102,12 @@
    void OnPlayerLoginOk()
    {
        //登录时有装备的处理
    }
    void BeforePlayerInit()
    {
        fightingHeroSkinID = 0;
        heroGuid = "";
    }
    public void SaveAutoFightSetting()
@@ -150,7 +159,7 @@
    }
    #region 战斗
    #region 主线战斗(自动和手动)
    public void StartFight()
    {
@@ -163,7 +172,7 @@
            return;
        }
        if (UIHelper.GetMoneyCnt(41) < PlayerDatas.Instance.baseData.UseHarmerCount)
        if (!ItemLogicUtility.CheckCurrencyCount(41, PlayerDatas.Instance.baseData.UseHarmerCount, 2))
        {
            if (storyBattleField.GetBattleMode() != BattleMode.Stop)
                storyBattleField.HaveRest();
@@ -190,12 +199,38 @@
    }
    void ChangeBattleModeEvent(BattleMode _battleMode)
    {
        if (_battleMode == BattleMode.Stop)
        {
            isAutoAttack = false;
        }
        OnFightEvent?.Invoke(false);
    }
    public int fightingHeroSkinID;  //当前战斗的英雄皮肤ID
    public string heroGuid;
    public event Action<bool> OnFightEvent; //是否战斗通知
    /// <summary>
    /// 技能释放 通知UI处理
    /// </summary>
    /// <param name="guid">空为主线</param>
    /// <param name="skillConfig">用于怒气等显示</param>
    /// <param name="teamHero">战斗中的武将</param>
    void OnSkillCast(string guid, SkillConfig skillConfig, TeamHero teamHero)
    {
        if (!string.IsNullOrEmpty(guid))
            return;
        if (teamHero.NPCID != 0)
            return;
        fightingHeroSkinID = teamHero.SkinID;
        heroGuid = teamHero.guid;
        OnFightEvent?.Invoke(true);
    }
    
    #endregion
Main/System/Main/MainWin.cs
@@ -15,6 +15,17 @@
    [SerializeField] Text powerText;
    [SerializeField] OfficialTitleCell officialRankText;
    //战斗按钮
    [SerializeField] Image fightOtherWinBG; //切换其他界面的显示
    [SerializeField] Image fightOtherWinWarnImg; //切换其他界面 如果是战斗中泛红提示
    [SerializeField] GameObject fightBG; //战斗界面显示
    [SerializeField] Image restImg; //休息状态
    [SerializeField] GameObject fightGo; //战斗状态
    [SerializeField] Image fightHeroImg; //战斗显示英雄
    [SerializeField] UIEffectPlayer fightEffect;
    [SerializeField] FillTween cdTween;
    public Text hammerText;
    protected override void InitComponent()
@@ -29,11 +40,13 @@
    {
        UpdateCurrency();
        UpdatePlayerInfo();
        RefreshFightBtn();
    }
    protected override void OnPreOpen()
    {
        PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefresh;
        AutoFightModel.Instance.OnFightEvent += OnSkillCast;
        base.OnPreOpen();
        // 刷新UI
@@ -43,6 +56,7 @@
    protected override void OnPreClose()
    {
        PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefresh;
        AutoFightModel.Instance.OnFightEvent -= OnSkillCast;
        base.OnPreClose();
    }
@@ -185,5 +199,106 @@
                Debug.LogWarning("未知的标签索引: " + functionOrder);
                break;
        }
        RefreshFightBtn();
    }
    ///战斗按钮显示规则
    /// 1.在主线战斗界面下:
    ///     1.1.休息状态的按钮
    ///     1.2.战斗状态的按钮 :显示下一个要攻击的武将头像,按位置顺序推算显示头像;严谨情况下需判断下一个武将是否可攻击如被眩晕等
    ///         有蒙版:默认显示播放其他战斗的状态,眩晕的状态等比较多(大多是蒙版显示的情况,根据实际看是否需要)
    ///         无蒙版:结束一个小通知的时候(B425)可以释放的去掉蒙版;有怒气的时候是否特殊表现(循环火特效?)
    ///         转圈:点击释放 播放特效且蒙版转圈,转圈结束后显示蒙版 -- 同时上方卡牌播放特效和转圈?
    /// 2.在非主线战斗界面下:
    ///     1. 休息显示关闭状态 无特效
    ///     2. 战斗中,显示泛红特效
    /// 上方卡牌 攻击时播放特效和转圈,有怒气的时候显示怒气特效?
    void RefreshFightBtn()
    {
        if (functionOrder == 0)
        {
            //主城界面
            fightOtherWinBG.SetActive(false);
            fightBG.SetActive(true);
            if (BattleManager.Instance.storyBattleField != null &&
            BattleManager.Instance.storyBattleField.GetBattleMode() == BattleMode.Stop)
            {
                fightGo.SetActive(false);
                restImg.SetActive(true);
            }
            else
            {
                fightGo.SetActive(true);
                restImg.SetActive(false);
                RefreshFightIng();
            }
        }
        else
        {
            //非主城界面
            fightOtherWinBG.SetActive(true);
            fightBG.SetActive(false);
            if (BattleManager.Instance.storyBattleField != null &&
            BattleManager.Instance.storyBattleField.GetBattleMode() == BattleMode.Stop)
            {
                fightOtherWinWarnImg.SetActive(false);
            }
            else
            {
                fightOtherWinWarnImg.SetActive(true);
            }
        }
    }
    void RefreshFightIng(bool isfighting = false)
    {
        if (isfighting)
        {
            // fightEffect.playDelayTime = 50;
            fightEffect.Play();
            cdTween.SetStartState();
            cdTween.Play(()=>
            {
                AutoFightModel.Instance.fightingHeroSkinID = TeamManager.Instance.GetTeam(TeamType.Story).GetNextServerHero(AutoFightModel.Instance.heroGuid).SkinID;
                fightHeroImg.SetSprite(HeroSkinConfig.Get(AutoFightModel.Instance.fightingHeroSkinID).SquareIcon);
            });
        }
        else
        {
            fightEffect.Stop();
            cdTween.Stop();
            cdTween.SetEndState();
        }
        if (AutoFightModel.Instance.fightingHeroSkinID == 0)
        {
            AutoFightModel.Instance.fightingHeroSkinID = TeamManager.Instance.GetTeam(TeamType.Story).GetNextServerHero(AutoFightModel.Instance.heroGuid).SkinID;
        }
        fightHeroImg.SetSprite(HeroSkinConfig.Get(AutoFightModel.Instance.fightingHeroSkinID).SquareIcon);
    }
    void OnSkillCast(bool isfighting)
    {
        if (functionOrder != 0)
            return;
        if (isfighting)
        {
            RefreshFightIng(isfighting);
        }
        else
        {
            RefreshFightBtn();
        }
    }
}
Main/System/Team/TeamBase.cs
@@ -188,6 +188,7 @@
        return null;
    }
    public TeamHero GetHeroByHeroID(int heroId)
    { 
        foreach (var hero in tempHeroes)
@@ -238,6 +239,40 @@
        return false;
    }
    public TeamHero GetNextServerHero(string guid)
    {
        if (string.IsNullOrEmpty(guid))
        {
            //取第一个
            foreach (var hero in serverHeroes)
            {
                if (hero != null)
                {
                    return hero;
                }
            }
            return null;
        }
        else
        {
            //取下一个
            bool findNext = false;
            foreach (var hero in serverHeroes)
            {
                if (hero != null && hero.guid == guid)
                {
                    findNext = true;
                }
                else if (findNext && hero != null)
                {
                    return hero;
                }
            }
            //没找到 取第一个
            return GetNextServerHero("");
        }
    }
    //客户端从0开始,服务端从1开始
    public int GetEmptyPosition()
    {