yyl
2025-10-29 f1e6527fd1a9281e254c000e21afb96c2da92e1c
125 战斗 追击反击连击效果 飘字效果更新
5个文件已修改
240 ■■■■ 已修改文件
Main/Component/UI/Common/SkeletonIllusionShadow.cs 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Motion/MotionBase.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Skill/SkillBase.cs 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/UIComp/BattleHeroInfoBar.cs 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/UIComp/BattleTips.cs 63 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Common/SkeletonIllusionShadow.cs
@@ -13,37 +13,40 @@
    private readonly List<GameObject> illusionShadows = new List<GameObject>();
    private SkeletonAnimation skeletonAnimation;
    private Color color = Color.white;
    private bool createSwitch = false;
    private int curFrame = 0;
    private int frameInteral = 4;
    private int frameInteral = 6;
    public void SetSkeletonAnimation(SkeletonAnimation _skeletonAnimation)
    {
        skeletonAnimation = _skeletonAnimation;
    }
    public void Show(bool v)
    public void Show(bool v, Color _color = default)
    {
        createSwitch = v;
        curFrame = 0;
        color = _color;
        
        if (!v)
        {
            // 清理所有残影对象
            for (int i = illusionShadows.Count - 1; i >= 0; i--)
            {
                var go = illusionShadows[i];
                if (go != null)
                {
                    DOTween.Kill(go, complete: false);
                    if (Application.isPlaying)
                        Destroy(go);
                    else
                        DestroyImmediate(go);
                }
            }
            illusionShadows.Clear();
            // for (int i = illusionShadows.Count - 1; i >= 0; i--)
            // {
            //     var go = illusionShadows[i];
            //     if (go != null)
            //     {
            //         DOTween.Kill(go, complete: false);
            //         if (Application.isPlaying)
            //             Destroy(go);
            //         else
            //             DestroyImmediate(go);
            //     }
            // }
            // illusionShadows.Clear();
        }
    }
@@ -91,9 +94,12 @@
        sa.timeScale = 0;
        RendererAdjuster parent = skeletonAnimation.GetComponentInParent<RendererAdjuster>();
        objTest.AddMissingComponent<RendererAdjuster>().SetSortingOrder(parent.sortingOrder);
        objTest.AddMissingComponent<RendererAdjuster>().SetSortingOrder(parent.sortingOrder - 1);
        sa.skeleton.A = skeletonAnimation.skeleton.A;
        sa.skeleton.R = color.r;
        sa.skeleton.G = color.g;
        sa.skeleton.B = color.b;
        sa.skeleton.A = 0.5F; //skeletonAnimation.skeleton.A;
        // 使用DoTween做alpha淡出,Tween与objTest绑定,便于统一Kill
        DOTween.To(() => sa.skeleton.A, x => { sa.skeleton.A = x; sa.LateUpdate(); }, 0f, 1f)
            .SetTarget(objTest);
Main/System/Battle/Motion/MotionBase.cs
@@ -382,12 +382,12 @@
        if (skeletonAnim != null) skeletonAnim.timeScale = ratio;
    }
    public void ShowIllusionShadow(bool isVisible)
    public void ShowIllusionShadow(bool isVisible, Color color = default)
    {
        if (illusionShadow != null)
        {
            illusionShadow.SetSkeletonAnimation(skeletonAnim);
            illusionShadow.Show(isVisible);
            illusionShadow.Show(isVisible, color);
        }
    }
}
Main/System/Battle/Skill/SkillBase.cs
@@ -9,6 +9,13 @@
{
    const float moveTime = 0.5f;
    private static readonly Color colorGreen = new Color(33f / 255f,
                                                        133f / 255f,
                                                        6f / 255f);
    private static readonly Color colorBlue = new Color(40f / 255f,
                                                        87f / 255f,
                                                        189f / 255f);
    protected SkillEffect skillEffect;
    protected HB427_tagSCUseSkill tagUseSkillAttack;
    public SkillConfig skillConfig;
@@ -23,6 +30,8 @@
    protected bool moveFinished = false;
    public int fromSkillId;
    public bool isPlay = false;
    private float MoveSpeed = 750f;
    private Dictionary<int, BattleDrops> tempDropList = new Dictionary<int, BattleDrops>();
    private Dictionary<int, HB422_tagMCTurnFightObjDead> tempDeadPackList = new Dictionary<int, HB422_tagMCTurnFightObjDead>();
@@ -76,6 +85,44 @@
        }
    }
    protected void ShadowIllutionCreate(bool create)
    {
        if (create)
        {
            Color color = Color.white;
            //1-连击;2-反击;3-追击
            //  反击蓝色
            //  追击连击绿色
            bool change = false;
            if (tagUseSkillAttack.BattleType == 1)
            {
                color = colorGreen;
                change = true;
            }
            else if (tagUseSkillAttack.BattleType == 2)
            {
                color = colorBlue;
                change = true;
            }
            else if (tagUseSkillAttack.BattleType == 3)
            {
                color = colorGreen;
                change = true;
            }
            if (change)
            {
                MoveSpeed = 1125f;
                caster.motionBase.ShowIllusionShadow(true, color);
            }
        }
        else
        {
            MoveSpeed = 750f;
            caster.motionBase.ShowIllusionShadow(false);
        }
    }
    // 技能释放主逻辑:广播事件、高亮目标、执行释放
    public virtual void Cast()
    {
@@ -104,6 +151,7 @@
            if (hintConfig != null)
            {
                caster.heroInfoBar.ShowTips(((char)hintConfig.prefix).ToString(), true);
                // Debug.Break();
            }
        }
@@ -148,7 +196,12 @@
        RectTransform target = battleField.GetTeamNode(caster.GetEnemyCamp(), skillConfig);
        ExecuteMoveAndCastSequence(target, () =>
        {
            MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, OnAttackFinish, 750F);
            // ShadowIllutionCreate(true);
            MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, () =>
            {
                // ShadowIllutionCreate(false);
                OnAttackFinish();
            }, MoveSpeed);
        });
    }
@@ -169,7 +222,12 @@
        ExecuteMoveAndCastSequence(targetTrans, () =>
        {
            RectTransform rectTransform = battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum);
            MoveToTarget(rectTransform, Vector2.zero, OnAttackFinish, 750F);
            // ShadowIllutionCreate(true);
            MoveToTarget(rectTransform, Vector2.zero, () =>
            {
                // ShadowIllutionCreate(false);
                OnAttackFinish();
            }, MoveSpeed);
        });
    }
@@ -179,17 +237,24 @@
        RectTransform target = battleField.GetTeamNode(caster.Camp, skillConfig);
        ExecuteMoveAndCastSequence(target, () =>
        {
            MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, OnAttackFinish, 750F);
            // ShadowIllutionCreate(true);
            MoveToTarget(battleField.GetTeamNode(caster.Camp, caster.teamHero.positionNum), Vector2.zero, () =>
            {
                // ShadowIllutionCreate(false);
                OnAttackFinish();
            }, MoveSpeed);
        });
    }
    // 执行移动-施法-返回序列:通用的移动攻击流程
    private void ExecuteMoveAndCastSequence(RectTransform target, Action onReturnComplete)
    {
        ShadowIllutionCreate(true);
        MoveToTarget(target, new Vector2(skillConfig.CastDistance, 0), () =>
        {
            TurnBack(() =>
            {
                ShadowIllutionCreate(false);
                CastImpl(() =>
                {
                    TurnBack(() => 
@@ -210,7 +275,7 @@
    }
    // 移动到目标位置:处理角色的移动动画和逻辑
    protected void MoveToTarget(RectTransform target, Vector2 offset, Action _onComplete = null, float speed = 500f)
    protected void MoveToTarget(RectTransform target, Vector2 offset, Action _onComplete = null, float speed = 750f)
    {
        if (skillConfig.CastDistance >= 9999)
        {
@@ -645,8 +710,8 @@
    public void OnSkillFinished()
    {
        // 修复:使用循环代替递归,避免栈溢出风险
        try
        {
        // try
        // {
            while (true)
            {
                // 验证技能效果是否完成
@@ -698,17 +763,22 @@
                }
                if (pack is CustomB421ActionPack actionPack)
                {
                    actionPack.Distribute();
                }
                else
                {
                PackageRegedit.Distribute(pack);
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"OnSkillFinished异常: {ex.Message},技能ID={skillConfig.SkillID}");
            // 确保状态一致性,即使出现异常也要标记完成
            isFinished = true;
            throw; // 重新抛出异常供上层处理
        }
        // }
        // catch (Exception ex)
        // {
        //     Debug.LogError($"OnSkillFinished异常: {ex.Message},技能ID={skillConfig.SkillID}");
        //     // 确保状态一致性,即使出现异常也要标记完成
        //     isFinished = true;
        //     throw; // 重新抛出异常供上层处理
        // }
        isFinished = true;
    }
Main/System/Battle/UIComp/BattleHeroInfoBar.cs
@@ -7,6 +7,13 @@
public class BattleHeroInfoBar : MonoBehaviour
{
    public class TipsInfo
    {
        public string message;
        public bool useArtText;
        public bool followCharacter;
    }
    protected BattleObject battleObject;
    public Slider sliderHp;
@@ -20,7 +27,7 @@
    [SerializeField] public List<BattleBuffCell> buffCells = new List<BattleBuffCell>();
    protected List<KeyValuePair<string, bool>> messages = new List<KeyValuePair<string, bool>>();
    protected List<TipsInfo> messages = new List<TipsInfo>();
    public BasicHeroInfoContainer heroInfoContainer;
 
@@ -80,9 +87,14 @@
        }
        tipsList.Clear();
    }
    public void ShowTips(string message, bool useArtText = false)
    public void ShowTips(string message, bool useArtText = false, bool followCharacter = false)
    {
        messages.Add(new KeyValuePair<string, bool>(message, useArtText));
        messages.Add(new TipsInfo
        {
            message = message,
            useArtText = useArtText,
            followCharacter = followCharacter
        });
    }
    public void SetActive(bool active)
@@ -90,13 +102,22 @@
        gameObject.SetActive(active);
    }
    public void PopUpTipsDirectly(string message, bool useArtText = false)
    public void PopUpTipsDirectly(string message, bool useArtText = false, bool followCharacter = false)
    {
        GameObject prefab = textTips.gameObject;
        GameObject go = GameObject.Instantiate(prefab, transform);
        GameObject go = GameObject.Instantiate(prefab, followCharacter ? transform : battleObject.battleField.battleRootNode.transform);
        BattleTips tips = go.GetComponent<BattleTips>();
        if (!followCharacter)
        {
            go.transform.position = prefab.transform.position;
            tips.beginPos = go.transform.localPosition;
            tips.endPos = tips.endPos + new Vector2(go.transform.localPosition.x, go.transform.localPosition.y);
        }
        tips.SetSpeedRatio(battleObject.battleField.speedRatio);
        tips.SetText(message, useArtText);
@@ -163,15 +184,15 @@
            tipsList[i].Run();
        }
        timer += Time.deltaTime;
        timer += 1f / (float)BattleConst.skillMotionFps * battleObject.battleField.speedRatio;
        if (messages.Count > 0 && timer >= PopUpInterval)
        {
            // 播放飘字
            KeyValuePair<string, bool> message = messages[0];
            TipsInfo message = messages[0];
            messages.RemoveAt(0);
            PopUpTipsDirectly(message.Key, message.Value);
            PopUpTipsDirectly(message.message, message.useArtText, message.followCharacter);
            timer = 0f;
        }
Main/System/Battle/UIComp/BattleTips.cs
@@ -1,4 +1,3 @@
using UnityEngine;
using System;
using UnityEngine.UI;
@@ -6,9 +5,16 @@
public class BattleTips : MonoBehaviour
{
    public Vector2 beginPos = Vector2.zero;
    public Vector2 endPos = new Vector2(0, 100);
    public float showTime = 0.4f;
    public Vector2 endPos = new Vector2(0, 150);
    public float scaleChangeTime = 0.2667f; // 7~8帧 (8/30=0.2667秒)
    public float totalShowTime = 0.8f; // 总时间约24帧 (8+16=24帧)
    public float timer = 0f;
    public Vector3 beginScale = new Vector3(4f, 4f, 4f);
    public Vector3 endScale = new Vector3(2f, 2f, 2f);
    public Color beginColor = new Color(1f, 1f, 1f, 0.5f);
    public Color endColor = new Color(1f, 1f, 1f, 1f);
    public RectTransform rectTransform;
@@ -18,21 +24,37 @@
    public Action OnFinish;
    private float speedRatio = 1f;
    public void SetSpeedRatio(float ratio)
    {
        speedRatio = ratio;
    }
    public void SetText(string text, bool useArtText = false)
    {
        rectTransform.anchoredPosition = Vector2.zero;
        //  初始放大200% 透明度50% 7~8帧内缩回100% 透明度到100% 再往上飘14~16帧 然后消失 (30帧/秒)
        // 8+16/30=0.8秒
        rectTransform.anchoredPosition = beginPos;
        rectTransform.localScale = beginScale;
        timer = 0f;
        gameObject.SetActive(true);
        if (useArtText)
        {
            artText.text = text;
            artText.color = beginColor;
            tipText.gameObject.SetActive(false);
            artText.gameObject.SetActive(true);
        }
        else
        {
            tipText.text = text;
            tipText.color = beginColor;
            artText.gameObject.SetActive(false);
            tipText.gameObject.SetActive(true);
        }
@@ -45,14 +67,41 @@
        if (!gameObject.activeSelf)
            return;
        if (timer >= showTime)
        if (timer >= totalShowTime)
        {
            gameObject.SetActive(false);
            OnFinish?.Invoke();
            OnFinish = null;
            return;
        }
        rectTransform.anchoredPosition = Vector2.Lerp(beginPos, endPos, timer / showTime);
        timer += Time.deltaTime;
        // 整个过程都往上飘
        float moveProgress = timer / totalShowTime;
        rectTransform.anchoredPosition = Vector2.Lerp(beginPos, endPos, moveProgress);
        // 阶段1: 7~8帧内缩放从beginScale到endScale,透明度从50%到100%
        if (timer < scaleChangeTime)
        {
            float scaleProgress = timer / scaleChangeTime;
            rectTransform.localScale = Vector3.Lerp(beginScale, endScale, scaleProgress);
            Color currentColor = Color.Lerp(beginColor, endColor, scaleProgress);
            if (tipText.gameObject.activeSelf)
                tipText.color = currentColor;
            if (artText.gameObject.activeSelf)
                artText.color = currentColor;
        }
        // 阶段2: 缩放完成后,保持endScale和100%透明度,继续往上飘
        else
        {
            rectTransform.localScale = endScale;
            if (tipText.gameObject.activeSelf)
                tipText.color = endColor;
            if (artText.gameObject.activeSelf)
                artText.color = endColor;
        }
        timer += 1f / (float)BattleConst.skillMotionFps * speedRatio;
    }
}