yyl
2 天以前 d90b3f1814240745b59c16af6c3e4aebe3451244
125 【战斗】战斗系统 掉落部分 技能特效部分
15个文件已修改
6个文件已添加
863 ■■■■ 已修改文件
Main/Common/EventName.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Effect/BattleEffectPlayer.cs 458 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Component/UI/Effect/BattleEffectPlayer.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleEffectMgr.cs 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/BattleField.cs 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/OperationAgent/StopModeOperationAgent.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/OperationAgent/StopModeOperationAgent.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/RecordActions/DeathRecordAction.cs 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleField/StoryBattleField.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/BattleObject/BattleObject.cs 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Define/BattleDrops.cs 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Define/BattleDrops.cs.meta 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/RecordPlayer/RecordPlayer.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/Skill/SkillBase.cs 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/SkillEffect/BulletCurve/BezierBulletCurve.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/SkillEffect/BulletCurve/BounceBulletCurve.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/SkillEffect/BulletCurve/BulletCurve.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/SkillEffect/BulletCurve/BulletCurveFactory.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/SkillEffect/BulletCurve/PenetrateBulletCurve.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/SkillEffect/BulletCurve/StraightBulletCurve.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/System/Battle/SkillEffect/BulletSkillEffect.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Common/EventName.cs
@@ -9,4 +9,6 @@
    public const string BATTLE_DAMAGE_TAKEN = "BATTLE_DAMAGE_TAKEN";//造成伤害
    
    public const string DISPLAY_BATTLE_UI = "DISPLAY_BATTLE_UI";//显示战斗UI
    public const string BATTLE_DROP_ITEMS = "BATTLE_DROP_ITEMS";//掉落物品
}
Main/Component/UI/Effect/BattleEffectPlayer.cs
New file
@@ -0,0 +1,458 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Spine.Unity;
using UnityEngine;
using Spine;
using UnityEngine.UI;
using System.Linq;
// 特效播放器,对象池管理:unity特效和spine特效都是做好的预制体
// unity特效预制体是特效师在制作的时候生成的,unity特效必须挂载设置播放时长脚本 EffectTime
// spine特效是特效师制作的动画文件可直接加载用,制作成预制体可增加BoneFollower之类的进行逻辑处理
public class BattleEffectPlayer : MonoBehaviour
{
    [SerializeField]
    private int m_EffectID;
    public int effectId
    {
        get
        {
            return m_EffectID;
        }
        set
        {
            if (value != m_EffectID)
            {
                isInit = false;
                m_EffectID = value;
            }
        }
    }
    public EffectConfig effectConfig;
    public float speedRate = 1f;
    [Header("播放完毕立即回收")]
    public bool isReleaseImmediately = false;  //界面特效一般不需要自我销毁,跟随界面或者父对象销毁就行
    public Action<BattleEffectPlayer> onDestroy;
    [HideInInspector] public Canvas canvas = null;
    [HideInInspector] public GameObject effectTarget = null;
    protected EffectPenetrationBlocker blocker = null;
    protected bool isInit = false;
    protected List<ParticleSystem> particleList = new List<ParticleSystem>();
    protected List<Animator> animatorList = new List<Animator>();
    protected List<Renderer> rendererList = new List<Renderer>();
    protected GameObject spineContainer;
    protected SkeletonGraphic spineComp;
    protected Spine.AnimationState spineAnimationState;
    public GameObjectPoolManager.GameObjectPool pool;
    public Action onComplete;
    protected virtual void OnEnable()
    {
        if (spineComp != null)
        {
            //隐藏,会有静态显示问题
            spineComp.enabled = false;
        }
    }
    protected void InitComponent(bool showLog = true)
    {
        Clear();
        if (effectId <= 0)
        {
            effectConfig = null;
#if UNITY_EDITOR
            if (showLog)
            {
                Debug.LogError("BattleEffectPlayer effectId is not set");
                UnityEditor.Selection.activeGameObject = gameObject;
                UnityEditor.EditorGUIUtility.PingObject(gameObject);
            }
#endif
            return;
        }
        effectConfig = EffectConfig.Get(effectId);
        if (null == effectConfig)
        {
#if UNITY_EDITOR
            Debug.LogError("could not find effect config, effect id is " + effectId);
            UnityEditor.Selection.activeGameObject = gameObject;
            UnityEditor.EditorGUIUtility.PingObject(gameObject);
#endif
            return;
        }
        //  初始化spine组件
        if (effectConfig != null && effectConfig.isSpine != 1)
        {
            GameObject spineContainerPrefab = ResManager.Instance.LoadAsset<GameObject>("UIComp", "SpineContainer");
            spineContainer = GameObject.Instantiate(spineContainerPrefab, transform);
        }
        //  有特效可能带spine又带unity特效的情况
        spineComp = gameObject.GetComponentInChildren<SkeletonGraphic>(true);
    }
    protected virtual void Clear()
    {
        particleList.Clear();
        animatorList.Clear();
        rendererList.Clear();
        spineComp = null;
        spineAnimationState = null;
        if (null != spineContainer)
            GameObject.DestroyImmediate(spineContainer);
        spineContainer = null;
        pool = null;
    }
    public virtual void Stop()
    {
        if (null != effectTarget)
        {
            // 如果使用了特效预制体池,则归还到池中
            if (pool != null)
            {
                pool.Release(effectTarget);
            }
            effectTarget = null;
        }
        isInit = false;
        Clear();
        onComplete?.Invoke();
    }
    public virtual void Play(bool showLog = true)
    {
        if (!isInit)
        {
            InitComponent(showLog);
            isInit = true;
        }
        else
        {
            //避免重复创建
            if (!this.gameObject.activeSelf)
            {
                this.gameObject.SetActive(true);
            }
            return;
        }
        if (EffectMgr.IsNotShowBySetting(effectId))
        {
            return;
        }
        if (null != effectTarget)
        {
            if (pool != null)
                pool.Release(effectTarget);
            effectTarget = null;
        }
        if (!this.gameObject.activeSelf)
        {
            this.gameObject.SetActive(true);
        }
        PlayEffect();
    }
    protected virtual void PlayEffect()
    {
        if (null == effectConfig)
        {
            Debug.LogError("BattleEffectPlayer effectConfig is null, effect id is " + effectId);
            return;
        }
        if (effectConfig.isSpine != 0)
        {
            PlaySpineEffect();
        }
        else
        {
            PlayUnityEffect();
        }
    }
    protected void PlaySpineEffect()
    {
        //  这里是纯spine的逻辑
        if (spineComp == null)
        {
            Debug.LogError("BattleEffectPlayer spineComp is null, effect id is " + effectId);
            return;
        }
        SkeletonDataAsset skeletonDataAsset = ResManager.Instance.LoadAsset<SkeletonDataAsset>("UIEffect/BattleSpine/" + effectConfig.packageName, effectConfig.fxName);
        spineComp.skeletonDataAsset = skeletonDataAsset;
        spineComp.Initialize(true);
        spineComp.raycastTarget = false;
        spineComp.timeScale = speedRate;
        spineAnimationState = spineComp.AnimationState;
        spineAnimationState.Complete -= OnSpineAnimationComplete;
        spineAnimationState.Complete += OnSpineAnimationComplete;
        Spine.Animation animation = spineAnimationState.Data.SkeletonData.Animations.First();
        spineAnimationState.SetAnimation(0, animation, false);
    }
    protected void PlayUnityEffect()
    {
        //  这里是纯unity特效的逻辑
        var effectPrefab = ResManager.Instance.LoadAsset<GameObject>("UIEffect/" + effectConfig.packageName, effectConfig.fxName);
        if (effectPrefab == null)
        {
            Debug.LogError($"加载UI特效失败: {effectConfig.packageName}");
            return;
        }
        if (spineComp != null)
        {
            spineComp.enabled = true;
        }
        // 从特效预制体池获取特效
        pool = GameObjectPoolManager.Instance.RequestPool(effectPrefab);
        effectTarget = pool.Request();
        // 设置父节点和位置
        effectTarget.transform.SetParent(transform);
        effectTarget.transform.localPosition = Vector3.zero;
        effectTarget.transform.localScale = Vector3.one;
        effectTarget.transform.localRotation = Quaternion.identity;
        effectTarget.name = $"Effect_{effectConfig.fxName}";
        //挂载组件后 开始收集
        particleList.AddRange(gameObject.GetComponentsInChildren<ParticleSystem>(true));
        animatorList.AddRange(gameObject.GetComponentsInChildren<Animator>(true));
        rendererList.AddRange(gameObject.GetComponentsInChildren<Renderer>(true));
        OnUnityAnimationComplete();
        if (null == canvas)
            canvas = GetComponentInParent<Canvas>();
        // 添加特效穿透阻挡器
        blocker = effectTarget.AddMissingComponent<EffectPenetrationBlocker>();
        //  如果没有canvas的话 正常是因为不在BattleWin下面的节点 意思就是当前没有显示 等到切回战斗的时候再通过BattleField.UpdateCanvas来更新
        if (canvas != null)
        {
            blocker.SetParentCanvas(canvas);
        }
        SoundPlayer.Instance.PlayUIAudio(effectConfig.audio);
    }
    protected void OnDestroy()
    {
        if (onDestroy != null)
        {
            onDestroy.Invoke(this);
            onDestroy = null;
        }
        // 停止特效并归还到池中
        Stop();
        if (spineAnimationState != null)
        {
            spineAnimationState.Complete -= OnSpineAnimationComplete;
        }
    }
    //单次播放完毕就会触发,即使是循环
    protected virtual void OnSpineAnimationComplete(Spine.TrackEntry trackEntry)
    {
        if (isReleaseImmediately)
        {
            spineComp.enabled = false;
            Stop();
        }
    }
    private void OnUnityAnimationComplete()
    {
        var timeObj = effectTarget.GetComponent<EffectTime>();
        if (!timeObj.isLoop)
        {
            this.SetWait(timeObj.playTime);
            this.DoWaitRestart();
            this.OnWaitCompelete(OnEffectComplete);
        }
    }
    private void OnEffectComplete(Component comp)
    {
        this.DoWaitStop();
        if (isReleaseImmediately)
            Stop();
    }
    //  创建后的特效会自动隐藏 需要手动调用Play才能播放
    public static BattleEffectPlayer Create(int effectId, Transform parent, bool createNewChild = false)
    {
        // 直接创建特效播放器,不使用对象池
        BattleEffectPlayer BattleEffectPlayer = null;
        if (createNewChild)
        {
            GameObject newGo = new GameObject("BattleEffectPlayer_" + effectId);
            newGo.transform.SetParent(parent, false);
            BattleEffectPlayer = newGo.AddComponent<BattleEffectPlayer>();
        }
        else
        {
            BattleEffectPlayer = parent.AddMissingComponent<BattleEffectPlayer>();
        }
        BattleEffectPlayer.effectId = effectId;
        BattleEffectPlayer.SetActive(true);
        return BattleEffectPlayer;
    }
    /// <summary>
    /// 设置游戏对象激活状态
    // /// </summary>
    // public void SetActive(bool active)
    // {
    //     if (gameObject != null)
    //     {
    //         gameObject.SetActive(active);
    //     }
    // }
    public void Pause()
    {
        if (effectTarget == null) return;
        // Spine动画
        // var spineGraphics = effectTarget.GetComponentsInChildren<SkeletonGraphic>(true);
        // foreach (var sg in spineGraphics)
        if (spineComp != null)
        {
            spineComp.timeScale = 0f;
        }
        // Animator动画
        foreach (var animator in animatorList)
        {
            animator.speed = 0f;
        }
        // 粒子特效
        foreach (var ps in particleList)
        {
            ps.Pause();
        }
    }
    public void Resume()
    {
        if (effectTarget == null) return;
        if (spineComp != null)
        {
            spineComp.timeScale = speedRate;
        }
        // Animator动画
        foreach (var animator in animatorList)
        {
            animator.speed = speedRate;
        }
        // 粒子特效
        foreach (var ps in particleList)
        {
            ps.Play();
        }
    }
    public bool IsFinish()
    {
        if (effectTarget == null) return true;
        // Spine动画
        if (!spineComp.AnimationState.GetCurrent(0).IsComplete)
        {
            return false;
        }
        // Animator动画
        foreach (var animator in animatorList)
        {
            AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
            //  循环动画不考虑结束的问题
            if (!stateInfo.loop && stateInfo.normalizedTime < 1f)
            {
                return false;
            }
        }
        // 粒子特效
        foreach (var ps in particleList)
        {
            if (ps.IsAlive())
            {
                return false;
            }
        }
        return true;
    }
    /// <summary>
    /// 设置遮罩(支持RectMask2D、Mask、SmoothMask等)
    /// </summary>
    public void SetMask(RectTransform maskArea = null)
    {
        if (effectTarget == null || blocker == null)
            return;
        // 优先使用传入的maskArea
        if (maskArea != null)
        {
            blocker.PerformMask(maskArea);
            return;
        }
    }
}
Main/Component/UI/Effect/BattleEffectPlayer.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 040308ab06e08de4ab5b2b8d0f192131
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Battle/BattleEffectMgr.cs
@@ -6,7 +6,7 @@
{
    private BattleField battleField;
    private Dictionary<int, List<EffectPlayer>> effectDict = new Dictionary<int, List<EffectPlayer>>();
    private Dictionary<int, List<BattleEffectPlayer>> effectDict = new Dictionary<int, List<BattleEffectPlayer>>();
    public void Init(BattleField _battleField)
    {
@@ -15,9 +15,9 @@
    public void PauseGame()
    {
        foreach (KeyValuePair<int, List<EffectPlayer>> kvPair in effectDict)
        foreach (KeyValuePair<int, List<BattleEffectPlayer>> kvPair in effectDict)
        {
            foreach (EffectPlayer effectPlayer in kvPair.Value)
            foreach (BattleEffectPlayer effectPlayer in kvPair.Value)
            {
                if (effectPlayer != null)
                {
@@ -29,9 +29,9 @@
    public void ResumeGame()
    {
        foreach (KeyValuePair<int, List<EffectPlayer>> kvPair in effectDict)
        foreach (KeyValuePair<int, List<BattleEffectPlayer>> kvPair in effectDict)
        {
            foreach (EffectPlayer effectPlayer in kvPair.Value)
            foreach (BattleEffectPlayer effectPlayer in kvPair.Value)
            {
                if (effectPlayer != null)
                {
@@ -41,14 +41,14 @@
        }
    }
    public EffectPlayer PlayEffect(int ObjID, int effectId, Transform parent)
    public BattleEffectPlayer PlayEffect(int ObjID, int effectId, Transform parent)
    {
        if (!effectDict.ContainsKey(effectId))
        {
            effectDict[effectId] = new List<EffectPlayer>();
            effectDict[effectId] = new List<BattleEffectPlayer>();
        }
        EffectPlayer effectPlayer = EffectPlayer.Create(effectId, parent);
        BattleEffectPlayer effectPlayer = BattleEffectPlayer.Create(effectId, parent);
        effectPlayer.onDestroy += OnEffectDestroy;
        if (effectPlayer != null)
        {
@@ -57,9 +57,9 @@
        return effectPlayer;
    }
    public void RemoveEffect(int effectId, EffectPlayer effectPlayer)
    public void RemoveEffect(int effectId, BattleEffectPlayer effectPlayer)
    {
        List<EffectPlayer> effectPlayers = null;
        List<BattleEffectPlayer> effectPlayers = null;
        if (effectDict.TryGetValue(effectId, out effectPlayers))
        {
@@ -73,7 +73,7 @@
        }
    }
    protected void OnEffectDestroy(EffectPlayer effectPlayer)
    protected void OnEffectDestroy(BattleEffectPlayer effectPlayer)
    {
        if (effectDict.ContainsKey(effectPlayer.effectId))
        {
@@ -87,9 +87,9 @@
    public void HaveRest()
    {
        foreach (KeyValuePair<int, List<EffectPlayer>> kvPair in effectDict)
        foreach (KeyValuePair<int, List<BattleEffectPlayer>> kvPair in effectDict)
        {
            foreach (EffectPlayer effectPlayer in kvPair.Value)
            foreach (BattleEffectPlayer effectPlayer in kvPair.Value)
            {
                if (effectPlayer != null)
                {
Main/System/Battle/BattleField/BattleField.cs
@@ -170,12 +170,21 @@
            case BattleMode.Record:
                operationAgent = new RecordModeOperationAgent(this);
                break;
            case BattleMode.Stop:
                operationAgent = new StopModeOperationAgent(this);
                break;
            default:
                operationAgent = new HandModeOperationAgent(this);
                break;
        }
        Debug.LogError("battleMode is " + battleMode.ToString());
    }
    public virtual void AutoSetBattleMode()
    {
        //  除了主线都是战报 主线的内容在StoryBattleField里
        SetBattleMode(BattleMode.Record);
    }
    public virtual void PlayRecord(RecordAction recordAction)
@@ -188,7 +197,7 @@
        recordPlayer.PlayRecord(recordList);
    }
    protected virtual void ResumeGame()
    public virtual void ResumeGame()
    {
        battleObjMgr.ResumeGame();
        recordPlayer.ResumeGame();
@@ -196,7 +205,7 @@
        battleTweenMgr.ResumeGame();
    }
    protected virtual void PauseGame()
    public virtual void PauseGame()
    {
        //  怎么通知界面暂停了呢?
@@ -382,14 +391,6 @@
        };
    }
    public void OnObjDropItem(int positionNum, ItemModel item)
    {
        // 处理掉落物品
        //无论如何图层应该在人物上面 所以这里应该有个挂点
        // YYL TODO
    }
    public void OnObjReborn(HB423_tagMCTurnFightObjReborn vNetData)
    {
@@ -405,12 +406,6 @@
        }
    }
    public void OnObjDropExp(BattleObject battleObject)
    {
        // 处理掉落经验
        // YYL TODO
        battleObject.DropExp();
    }
    public virtual void OnBattleEnd(JsonData turnFightStateData)
    {
@@ -429,6 +424,8 @@
        battleEffectMgr.HaveRest();
        battleTweenMgr.HaveRest();
        SetBattleMode(BattleMode.Stop);
    }
    public bool IsBattleEnd()
@@ -440,4 +437,4 @@
    {
    }
}
}
Main/System/Battle/BattleField/OperationAgent/StopModeOperationAgent.cs
New file
@@ -0,0 +1,23 @@
using UnityEngine;
//    record直接全程播放就好了 不需要其他操作
public class StopModeOperationAgent : IOperationAgent
{
    public StopModeOperationAgent(BattleField battleField) : base(battleField)
    {
    }
    public override void Run()
    {
        base.Run();
    }
    public override void DoNext()
    {
        base.DoNext();
        battleField.AutoSetBattleMode();
    }
}
Main/System/Battle/BattleField/OperationAgent/StopModeOperationAgent.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3326f5db1168c3f48922e1c2c1a07b50
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Battle/BattleField/RecordActions/DeathRecordAction.cs
@@ -8,7 +8,6 @@
        : base(RecordActionType.Death, _battleField, _battleObj)
    {
        isFinish = false;
        isRunOnce = false;
    }
    public override bool IsFinished()
@@ -19,12 +18,8 @@
    public override void Run()
    {
        if (isRunOnce)
        {
            return;
        }
        base.Run();
        isRunOnce = true;
        isFinish = true;
        battleObject.OnDeath(OnDeathAnimationEnd);
    }
@@ -33,18 +28,7 @@
        //  只有主线掉落物品
        if (battleField.MapID == 1 || battleField.MapID == 2)
        {
            var dropItemPack = PackManager.Instance.GetSinglePack(PackType.DropItem);
            if (dropItemPack != null)
            {
                var items = dropItemPack.GetAllItems();
                foreach (ItemModel item in items.Values)
                {
                    //    掉落物品
                    battleField.OnObjDropItem(battleObject.teamHero.positionNum, item);
                    battleField.OnObjDropExp(battleObject);
                }
            }
            battleObject.PerformDrop();
        }
        // 掉落物品 增加经验
Main/System/Battle/BattleField/StoryBattleField.cs
@@ -78,6 +78,11 @@
        SetBattleMode((BattleMode)Enum.Parse(typeof(BattleMode), savedStr));
    }
    public override void AutoSetBattleMode()
    {
        LoadBattleMode();
    }
    public override void TurnFightState(int TurnNum, int State,
        uint FuncLineID, JsonData extendData)
    {
Main/System/Battle/BattleObject/BattleObject.cs
@@ -48,6 +48,8 @@
        private set;
    }
    protected BattleDrops battleDrops;
    private RectTransform m_heroRectTrans;
    public RectTransform heroRectTrans
@@ -328,16 +330,23 @@
        motionBase.PlayAnimation(MotionName.idle, true);
    }
    public void PushExpPackList(List<HB405_tagMCAddExp> _hB405_tagMCAddExps)
    public void PushDropItems(BattleDrops _battleDrops)
    {
        // YYL TODO 死亡后弹出经验掉落提醒
        hB405_tagMCAddExps = _hB405_tagMCAddExps;
        battleDrops = _battleDrops;
    }
    public void DropExp()
    public void PerformDrop()
    {
        // YYL TODO
        // hB405_tagMCAddExps
        if (null == battleDrops)
            return;
        EventBroadcast.Instance.Broadcast<string, BattleDrops, Action>(
            EventName.BATTLE_DROP_ITEMS, battleField.guid, battleDrops, OnPerformDropFinish);
    }
    protected void OnPerformDropFinish()
    {
        battleDrops = null;
    }
Main/System/Battle/Define/BattleDrops.cs
New file
@@ -0,0 +1,14 @@
using System.Collections.Generic;
using UnityEngine;
public class BattleDrops
{
    //  掉落位置
    public RectTransform rectTransform;
    //  平均分配好后的掉落物品背包索引列表
    public List<int> dropItemPackIndex = new List<int>();
    //  平均分配好后的经验掉落
    public List<HB405_tagMCAddExp> expDrops = new List<HB405_tagMCAddExp>();
}
Main/System/Battle/Define/BattleDrops.cs.meta
New file
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 99a36d208918d0f47bd97c12803e435d
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:
Main/System/Battle/RecordPlayer/RecordPlayer.cs
@@ -52,6 +52,8 @@
        if (currentRecordAction != null && currentRecordAction.IsFinished())
        {
            Debug.LogError("record action " + currentRecordAction.GetType() + " play finished");
            currentRecordAction = null;
        }
Main/System/Battle/Skill/SkillBase.cs
@@ -3,6 +3,8 @@
using System;
using DG.Tweening;
using Spine;
using System.Linq;
using PlasticGui.WorkspaceWindow.BranchExplorer;
public class SkillBase
@@ -65,20 +67,7 @@
    }
    protected virtual void OnActiveSkillFrame()
    {
    }
    protected virtual void OnStartSkillFrame()
    {
    }
    protected virtual void OnEndSkillFrame()
    {
    }
    public void Pause()
    {
@@ -141,26 +130,10 @@
        }
    }
    //    冲刺的技能 动作 跟移动 是同时进行的 移动到目标的一瞬间就要进行技能逻辑
    // protected void DashToTarget(Action _onComplete)
    // {
    //     TrackEntry entry = PlayCastAnimation();
    //     BattleObject mainTarget = battleField.battleObjMgr.GetBattleObject((int)tagUseSkillAttack.AttackID);
    //     if (mainTarget == null)
    //     {
    //         Debug.LogError("目标为空 mainTarget == null AttackID : " + tagUseSkillAttack.AttackID);
    //         _onComplete?.Invoke();
    //         return;
    //     }
    //     //    做一个微微的提前
    //     MoveToTarget(mainTarget.Camp, mainTarget.teamHero.positionNum, entry.AnimationEnd - 0.05f, () => DoSkillLogic(_onComplete));
    // }
    //    这里其实是技能后摇结束的地方
    protected virtual void DoSkillLogic(Action _onComplete = null)
    {
    }
    protected TrackEntry PlayCastAnimation(Action onComplete = null)
@@ -226,7 +199,7 @@
        // 高亮所有目标
        HashSet<BattleObject> highlightList = new HashSet<BattleObject>(battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack));
        highlightList.Add(caster);
        //    把这些BO全高亮 或者说把除了这些的都放在遮罩后面
        //    YYL TODO
@@ -256,7 +229,103 @@
            OnHitEachTarget(target, totalDamage, damageList, ref hurt);
        }
    }
        HandleDead();
    }
    protected void HandleDead()
    {
        var deadPackList = FindDeadPack();
        CheckAfterDeadhPack();
        // 处理掉落包 提前distribute之后 PackManager才有掉落物 所以不跟assignexp一样distribute
        foreach (var _dropPack in dropPackList)
        {
            PackageRegedit.Distribute(_dropPack);
            packList.Remove(_dropPack);
        }
        // 获取掉落物品
        var dropPack = PackManager.Instance.GetSinglePack(PackType.DropItem);
        var itemDict = dropPack.GetAllItems();
        List<ItemModel> itemList = new List<ItemModel>(
            from item in itemDict.Values
            where item != null && item.isAuction
            select item);
        int deadCount = deadPackList.Count;
        // 分配掉落和经验
        var dropAssign = AssignDrops(itemList, deadCount);
        var expAssign = AssignExp(expPackList, deadCount);
        // 构造 BattleDrops 并分配
        for (int i = 0; i < deadCount; i++)
        {
            BattleObject deadTarget = battleField.battleObjMgr.GetBattleObject((int)deadPackList[i].ObjID);
            List<ItemModel> itemModelDrops = dropAssign[i];
            List<int> itemModelDropsIndexList = new List<int>(
                from item in itemModelDrops  select item.gridIndex);
            BattleDrops battleDrops = new BattleDrops()
            {
                rectTransform = deadTarget.heroRectTrans,
                dropItemPackIndex = itemModelDropsIndexList,
                expDrops = expAssign[i]
            };
            deadTarget.PushDropItems(battleDrops);
        }
        // 分发死亡包
        foreach (var deadPack in deadPackList)
        {
            PackageRegedit.Distribute(deadPack);
            packList.Remove(deadPack);
        }
        deadPackList.Clear();
    }
    // 分配掉落
    protected List<List<ItemModel>> AssignDrops(List<ItemModel> itemList, int deadCount)
    {
        var dropAssign = new List<List<ItemModel>>(deadCount);
        for (int i = 0; i < deadCount; i++)
            dropAssign.Add(new List<ItemModel>());
        for (int i = 0; i < itemList.Count; i++)
            dropAssign[i % deadCount].Add(itemList[i]);
        return dropAssign;
    }
    // 分配经验:每个原始包都平均分配到每个死亡对象
    protected List<List<HB405_tagMCAddExp>> AssignExp(List<HB405_tagMCAddExp> expList, int deadCount)
    {
        var expAssign = new List<List<HB405_tagMCAddExp>>(deadCount);
        for (int i = 0; i < deadCount; i++)
            expAssign.Add(new List<HB405_tagMCAddExp>());
        foreach (var expPack in expList)
        {
            long totalExp = GeneralDefine.GetFactValue(expPack.Exp, expPack.ExpPoint);
            long avgExp = totalExp / deadCount;
            long remain = totalExp % deadCount;
            for (int i = 0; i < deadCount; i++)
            {
                long assignExp = avgExp + (i < remain ? 1 : 0);
                long expPoint = assignExp / 100000000;
                long exp = assignExp % 100000000;
                var newPack = new HB405_tagMCAddExp
                {
                    Exp = (uint)exp,
                    ExpPoint = (uint)expPoint,
                    Source = expPack.Source // 保持原包来源
                };
                expAssign[i].Add(newPack);
            }
            packList.Remove(expPack);
        }
        return expAssign;
    }
    /// <summary>
    /// 保证所有分配项加起来等于totalDamage,避免因整除导致的误差
@@ -299,41 +368,6 @@
                target.heroGo.transform
            );
        }
        //    受伤之后辨别死亡状态 死亡包其实前后帧会多次触发 应该要即时remove其他的包来保证不重复
        if (target.IsDead())
        {
            // SkillRecordAction里的drop事件前移到dead之后
            HB422_tagMCTurnFightObjDead deadPack = FindDeadPack(target);
            CheckAfterDeadhPack(target, deadPack);
            if (deadPack != null)
            {
                //    处理掉落包
                for (int i = 0; i < dropPackList.Count; i++)
                {
                    PackageRegedit.Distribute(dropPackList[i]);
                }
                dropPackList.Clear();
                target.PushExpPackList(new List<HB405_tagMCAddExp>(expPackList));
                expPackList.Clear();
                // 处理死亡包
                PackageRegedit.Distribute(deadPack);
                packList.Remove(deadPack);
            }
            //    复活包暂时不管 可能是技能的包
            // HB423_tagMCTurnFightObjReborn rebornPack = FindRebornPack(target);
            // if (rebornPack != null)
            // {
            //     //    处理复活包
            //     PackageRegedit.Distribute(rebornPack);
            //     packList.Remove(rebornPack);
            // }
        }
    }
    protected HB423_tagMCTurnFightObjReborn FindRebornPack(BattleObject target)
@@ -362,20 +396,17 @@
        return null;
    }
    protected HB422_tagMCTurnFightObjDead FindDeadPack(BattleObject target)
    protected List<HB422_tagMCTurnFightObjDead> FindDeadPack()
    {
        HB422_tagMCTurnFightObjDead deadPack = null;
        List<HB422_tagMCTurnFightObjDead> deadPacks = new List<HB422_tagMCTurnFightObjDead>();
        for (int i = 0; i < packList.Count; i++)
        {
            var pack = packList[i];
            //    寻找死亡包 找到死亡包之后要找掉落包 不能超过技能包
            if (pack is HB422_tagMCTurnFightObjDead)
            {
                deadPack = pack as HB422_tagMCTurnFightObjDead;
                if (deadPack.ObjID == target.ObjID)
                {
                    return deadPack;
                }
                var deadPack = pack as HB422_tagMCTurnFightObjDead;
                deadPacks.Add(deadPack);
            }
            else if (pack is CustomHB426CombinePack)
            {
@@ -387,22 +418,13 @@
                }
            }
        }
        return null;
        return deadPacks;
    }
    protected void CheckAfterDeadhPack(BattleObject target, HB422_tagMCTurnFightObjDead deadPack)
    protected void CheckAfterDeadhPack()
    {
        if (null == deadPack)
        {
            return;
        }
        var deadPackIndex = packList.IndexOf(deadPack);
        if (deadPackIndex < 0)
        {
            return;
        }
        List<int> removeIndexList = new List<int>();
        for (int i = deadPackIndex + 1; i < packList.Count; i++)
        for (int i = 0; i < packList.Count; i++)
        {
            var pack = packList[i];
@@ -485,4 +507,20 @@
        isFinished = true;
    }
    protected virtual void OnActiveSkillFrame()
    {
    }
    protected virtual void OnStartSkillFrame()
    {
    }
    protected virtual void OnEndSkillFrame()
    {
    }
}
Main/System/Battle/SkillEffect/BulletCurve/BezierBulletCurve.cs
@@ -8,7 +8,7 @@
    private Vector2 end;
    private Vector2 control;
    public BezierBulletCurve(BattleObject caster, SkillConfig skillConfig, EffectPlayer effectPlayer, RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit)
    public BezierBulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer effectPlayer, RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit)
        : base(caster, skillConfig, effectPlayer, target, onHit) { }
    public override void Reset()
Main/System/Battle/SkillEffect/BulletCurve/BounceBulletCurve.cs
@@ -14,7 +14,7 @@
    private float bounceTime = 0.2f; // 每次弹射时间
    private float bounceElapsed = 0f;
    public BounceBulletCurve(BattleObject caster, SkillConfig skillConfig, EffectPlayer effectPlayer,
    public BounceBulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer effectPlayer,
        RectTransform target, HB427_tagSCUseSkill tagUseSkillAttack, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit)
        : base(caster, skillConfig, effectPlayer, target, onHit)
    {
Main/System/Battle/SkillEffect/BulletCurve/BulletCurve.cs
@@ -6,7 +6,7 @@
{
    protected BattleObject caster;
    protected SkillConfig skillConfig;
    protected EffectPlayer bulletEffect;
    protected BattleEffectPlayer bulletEffect;
    protected RectTransform bulletTrans; // 子弹的RectTransform
    protected RectTransform target;
    protected Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit;
@@ -17,7 +17,7 @@
    public BulletCurve() { }
    public BulletCurve(BattleObject caster, SkillConfig skillConfig, EffectPlayer bulletEffect, RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit)
    public BulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer bulletEffect, RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit)
    {
        this.caster = caster;
        this.skillConfig = skillConfig;
Main/System/Battle/SkillEffect/BulletCurve/BulletCurveFactory.cs
@@ -13,7 +13,7 @@
    public static BulletCurve CreateBulletCurve(
        BattleObject caster,
        SkillConfig skillConfig,
        EffectPlayer bulletEffect,
        BattleEffectPlayer bulletEffect,
        RectTransform target,
        HB427_tagSCUseSkill tagUseSkillAttack,
        Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit)
Main/System/Battle/SkillEffect/BulletCurve/PenetrateBulletCurve.cs
@@ -9,7 +9,7 @@
    private Vector2 outPos;     // 屏幕外延长点(本地坐标)
    private bool hitTriggered = false; // 是否已触发onHit
    public PenetrateBulletCurve(BattleObject caster, SkillConfig skillConfig, EffectPlayer effectPlayer, RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit)
    public PenetrateBulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer effectPlayer, RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit)
        : base(caster, skillConfig, effectPlayer, target, onHit) { }
    /// <summary>
Main/System/Battle/SkillEffect/BulletCurve/StraightBulletCurve.cs
@@ -7,7 +7,7 @@
    private Vector2 start;
    private Vector2 end;
    public StraightBulletCurve(BattleObject caster, SkillConfig skillConfig, EffectPlayer bulletEffect, RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit)
    public StraightBulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer bulletEffect, RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit)
        : base(caster, skillConfig, bulletEffect, target, onHit) { }
    public override void Reset()
Main/System/Battle/SkillEffect/BulletSkillEffect.cs
@@ -79,7 +79,7 @@
    protected void ShotToFormation(RectTransform target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> _onHit)
    {
        EffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.BulletEffectId, caster.effectNode);
        BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.BulletEffectId, caster.effectNode);
        RectTransform effectTrans = effectPlayer.transform as RectTransform;
@@ -113,7 +113,7 @@
    protected void ShotToTarget(BattleObject target, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> _onHit)
    {
        EffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.BulletEffectId, caster.effectNode);
        BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster.ObjID, skillConfig.BulletEffectId, caster.effectNode);
        RectTransform effectTrans = effectPlayer.transform as RectTransform;
        var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, target.heroRectTrans, tagUseSkillAttack, (index, hitList) =>