| | |
| | | typeof(PlayerAttrConfig),
|
| | | typeof(PlayerFaceConfig),
|
| | | typeof(PresetUnlockConfig),
|
| | | typeof(PriorBundleConfig),
|
| | | typeof(RandomNameConfig),
|
| | | typeof(SignInConfig),
|
| | | typeof(SkillSkinConfig),
|
| | | typeof(StoreConfig),
|
| | | typeof(SuccessConfig),
|
| | | typeof(SysInfoConfig),
|
| | |
| | | ClearConfigDictionary<PlayerFaceConfig>();
|
| | | // 清空 PresetUnlockConfig 字典
|
| | | ClearConfigDictionary<PresetUnlockConfig>();
|
| | | // 清空 PriorBundleConfig 字典
|
| | | ClearConfigDictionary<PriorBundleConfig>();
|
| | | // 清空 RandomNameConfig 字典
|
| | | ClearConfigDictionary<RandomNameConfig>();
|
| | | // 清空 SignInConfig 字典
|
| | | ClearConfigDictionary<SignInConfig>();
|
| | | // 清空 SkillSkinConfig 字典
|
| | | ClearConfigDictionary<SkillSkinConfig>();
|
| | | // 清空 StoreConfig 字典
|
| | | ClearConfigDictionary<StoreConfig>();
|
| | | // 清空 SuccessConfig 字典
|
| | |
| | | //--------------------------------------------------------
|
| | | // [Author]: YYL
|
| | | // [ Date ]: 2025年12月12日
|
| | | // [ Date ]: 2026年2月7日
|
| | | //--------------------------------------------------------
|
| | |
|
| | | using System.Collections.Generic;
|
| | |
| | | public int[] BuffStateLimit;
|
| | | public int BuffState;
|
| | | public int FightPower;
|
| | | public string SkillMotionName;
|
| | | public string IconName;
|
| | | public string BuffIconName;
|
| | | public string SkillTipsName;
|
| | | public int EffectType;
|
| | | public int StartupFrames;
|
| | | public int[] ActiveFrames;
|
| | | public int RecoveryFrames;
|
| | | public int LoopCount;
|
| | | public int CastPosition;
|
| | | public int CastIndexNum;
|
| | | public float CastDistance;
|
| | | public int[][] DamageDivide;
|
| | | public int BulletEffectId;
|
| | | public int BulletPath;
|
| | | public float BulletFlySpeed;
|
| | | public int Scattering;
|
| | | public int ExplosionEffectId;
|
| | | public int ExplosionEffect2;
|
| | | public int ExplosionEffect3;
|
| | | public int ExplosionEffect4;
|
| | | public int EffectId;
|
| | | public int EffectId2;
|
| | | public int SkinllSFX1;
|
| | | public int SkinllSFX2;
|
| | | public int MStartEffectId;
|
| | | public int BuffEffect;
|
| | | public int TriggerEffect;
|
| | | public int ClientTriggerTiming;
|
| | |
|
| | | public override int LoadKey(string _key)
|
| | |
| | |
|
| | | int.TryParse(tables[18],out FightPower);
|
| | |
|
| | | SkillMotionName = tables[19];
|
| | | IconName = tables[19];
|
| | |
|
| | | IconName = tables[20];
|
| | | BuffIconName = tables[20];
|
| | |
|
| | | BuffIconName = tables[21];
|
| | | SkillTipsName = tables[21];
|
| | |
|
| | | SkillTipsName = tables[22];
|
| | | int.TryParse(tables[22],out Scattering); |
| | |
|
| | | int.TryParse(tables[23],out EffectType); |
| | |
|
| | | int.TryParse(tables[24],out StartupFrames); |
| | |
|
| | | if (tables[25].Contains("[")) |
| | | { |
| | | ActiveFrames = JsonMapper.ToObject<int[]>(tables[25]); |
| | | } |
| | | else |
| | | { |
| | | string[] ActiveFramesStringArray = tables[25].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | ActiveFrames = new int[ActiveFramesStringArray.Length]; |
| | | for (int i=0;i<ActiveFramesStringArray.Length;i++) |
| | | { |
| | | int.TryParse(ActiveFramesStringArray[i],out ActiveFrames[i]); |
| | | } |
| | | }
|
| | |
|
| | | int.TryParse(tables[26],out RecoveryFrames); |
| | |
|
| | | int.TryParse(tables[27],out LoopCount); |
| | |
|
| | | int.TryParse(tables[28],out CastPosition); |
| | |
|
| | | int.TryParse(tables[29],out CastIndexNum); |
| | |
|
| | | float.TryParse(tables[30],out CastDistance); |
| | |
|
| | | DamageDivide = JsonMapper.ToObject<int[][]>(tables[31].Replace("(", "[").Replace(")", "]")); |
| | |
|
| | | int.TryParse(tables[32],out BulletEffectId); |
| | |
|
| | | int.TryParse(tables[33],out BulletPath); |
| | |
|
| | | float.TryParse(tables[34],out BulletFlySpeed); |
| | |
|
| | | int.TryParse(tables[35],out Scattering); |
| | |
|
| | | int.TryParse(tables[36],out ExplosionEffectId); |
| | |
|
| | | int.TryParse(tables[37],out ExplosionEffect2); |
| | |
|
| | | int.TryParse(tables[38],out ExplosionEffect3); |
| | |
|
| | | int.TryParse(tables[39],out ExplosionEffect4); |
| | |
|
| | | int.TryParse(tables[40],out EffectId); |
| | |
|
| | | int.TryParse(tables[41],out EffectId2); |
| | |
|
| | | int.TryParse(tables[42],out SkinllSFX1); |
| | |
|
| | | int.TryParse(tables[43],out SkinllSFX2); |
| | |
|
| | | int.TryParse(tables[44],out MStartEffectId); |
| | |
|
| | | int.TryParse(tables[45],out BuffEffect); |
| | |
|
| | | int.TryParse(tables[46],out TriggerEffect); |
| | |
|
| | | int.TryParse(tables[47],out ClientTriggerTiming); |
| | | int.TryParse(tables[23],out ClientTriggerTiming); |
| | | }
|
| | | catch (Exception exception)
|
| | | {
|
| New file |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2026年2月7日 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | | using System; |
| | | using UnityEngine; |
| | | using LitJson; |
| | | |
| | | public partial class SkillSkinConfig : ConfigBase<string, SkillSkinConfig> |
| | | { |
| | | static SkillSkinConfig() |
| | | { |
| | | // 访问过静态构造函数 |
| | | visit = true; |
| | | } |
| | | |
| | | public string SkillSkinID; |
| | | public string SkillMotionName; |
| | | public int EffectType; |
| | | public int CastPosition; |
| | | public int CastIndexNum; |
| | | public float CastDistance; |
| | | public int StartupFrames; |
| | | public int[] ActiveFrames; |
| | | public int RecoveryFrames; |
| | | public int LoopCount; |
| | | public int[][] DamageDivide; |
| | | public int BulletEffectId; |
| | | public int BulletPath; |
| | | public float BulletFlySpeed; |
| | | public int ExplosionEffectId; |
| | | public int ExplosionEffect2; |
| | | public int ExplosionEffect3; |
| | | public int ExplosionEffect4; |
| | | public int EffectId; |
| | | public int EffectId2; |
| | | public int SkinllSFX1; |
| | | public int SkinllSFX2; |
| | | public int MStartEffectId; |
| | | public int BuffEffect; |
| | | public int TriggerEffect; |
| | | |
| | | public override string LoadKey(string _key) |
| | | { |
| | | string key = GetKey(_key); |
| | | return key; |
| | | } |
| | | |
| | | public override void LoadConfig(string input) |
| | | { |
| | | try { |
| | | string[] tables = input.Split('\t'); |
| | | SkillSkinID = tables[0]; |
| | | |
| | | SkillMotionName = tables[1]; |
| | | |
| | | int.TryParse(tables[2],out EffectType); |
| | | |
| | | int.TryParse(tables[3],out CastPosition); |
| | | |
| | | int.TryParse(tables[4],out CastIndexNum); |
| | | |
| | | float.TryParse(tables[5],out CastDistance); |
| | | |
| | | int.TryParse(tables[6],out StartupFrames); |
| | | |
| | | if (tables[7].Contains("[")) |
| | | { |
| | | ActiveFrames = JsonMapper.ToObject<int[]>(tables[7]); |
| | | } |
| | | else |
| | | { |
| | | string[] ActiveFramesStringArray = tables[7].Trim().Split(StringUtility.splitSeparator,StringSplitOptions.RemoveEmptyEntries); |
| | | ActiveFrames = new int[ActiveFramesStringArray.Length]; |
| | | for (int i=0;i<ActiveFramesStringArray.Length;i++) |
| | | { |
| | | int.TryParse(ActiveFramesStringArray[i],out ActiveFrames[i]); |
| | | } |
| | | } |
| | | |
| | | int.TryParse(tables[8],out RecoveryFrames); |
| | | |
| | | int.TryParse(tables[9],out LoopCount); |
| | | |
| | | DamageDivide = JsonMapper.ToObject<int[][]>(tables[10].Replace("(", "[").Replace(")", "]")); |
| | | |
| | | int.TryParse(tables[11],out BulletEffectId); |
| | | |
| | | int.TryParse(tables[12],out BulletPath); |
| | | |
| | | float.TryParse(tables[13],out BulletFlySpeed); |
| | | |
| | | int.TryParse(tables[14],out ExplosionEffectId); |
| | | |
| | | int.TryParse(tables[15],out ExplosionEffect2); |
| | | |
| | | int.TryParse(tables[16],out ExplosionEffect3); |
| | | |
| | | int.TryParse(tables[17],out ExplosionEffect4); |
| | | |
| | | int.TryParse(tables[18],out EffectId); |
| | | |
| | | int.TryParse(tables[19],out EffectId2); |
| | | |
| | | int.TryParse(tables[20],out SkinllSFX1); |
| | | |
| | | int.TryParse(tables[21],out SkinllSFX2); |
| | | |
| | | int.TryParse(tables[22],out MStartEffectId); |
| | | |
| | | int.TryParse(tables[23],out BuffEffect); |
| | | |
| | | int.TryParse(tables[24],out TriggerEffect); |
| | | } |
| | | catch (Exception exception) |
| | | { |
| | | Debug.LogError(exception); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 16994c332e272e048a0ce72b27c91aaf |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | public static readonly int[] DebuffSkillType = new int[] { 4, 6, 14 }; |
| | | |
| | | public SkillType skillType; |
| | | public SkillCastMode castMode; |
| | | |
| | | public SkillEffectType effectType; |
| | | protected SkillSkinConfig originSkinConfig; |
| | | |
| | | //技能类型:技能等级:技能 |
| | | static Dictionary<int, Dictionary<int, SkillConfig>> skillDics = new Dictionary<int, Dictionary<int, SkillConfig>>(); |
| | |
| | | base.OnConfigParseCompleted(); |
| | | |
| | | skillType = (SkillType)SkillType; |
| | | castMode = (SkillCastMode)CastPosition; |
| | | effectType = (SkillEffectType)EffectType; |
| | | |
| | | if (DamageDivide == null || DamageDivide.Length == 0) |
| | | { |
| | | DamageDivide = new int[1][]; |
| | | DamageDivide[0] = new int[] { 10000 }; |
| | | } |
| | | |
| | | // #if UNITY_EDITOR |
| | | // if (Launch.Instance.isOpenBattleDebug) |
| | | // { |
| | | // if (castMode == SkillCastMode.None) |
| | | // { |
| | | // castMode = SkillCastMode.Target; |
| | | // } |
| | | // } |
| | | // #endif |
| | | |
| | | Dictionary<int, SkillConfig> tempDic = null; |
| | | if (!skillDics.TryGetValue((int)skillType, out tempDic)) |
| | |
| | | skillDics.Add((int)skillType, tempDic); |
| | | } |
| | | tempDic[SkillLV] = this; |
| | | } |
| | | |
| | | public SkillSkinConfig GetSkillSkinConfig(int skinID) |
| | | { |
| | | string key = skinID.ToString() + SkillID.ToString(); |
| | | |
| | | SkillSkinConfig skillSkinConfig = SkillSkinConfig.Get(key); |
| | | |
| | | if (null == skillSkinConfig) |
| | | { |
| | | return GetOriginSkinConfig(); |
| | | } |
| | | else |
| | | { |
| | | return skillSkinConfig; |
| | | } |
| | | } |
| | | |
| | | public SkillSkinConfig GetOriginSkinConfig() |
| | | { |
| | | if (originSkinConfig == null) |
| | | { |
| | | originSkinConfig = SkillSkinConfig.Get(SkillID.ToString()); |
| | | } |
| | | if (null == originSkinConfig) |
| | | { |
| | | Debug.LogError("找不到技能皮肤配置 " + SkillID); |
| | | return null; |
| | | } |
| | | else |
| | | { |
| | | return originSkinConfig; |
| | | } |
| | | } |
| | | |
| | | public bool IsGainBuff() |
| | |
| | | { |
| | | return Array.Exists(DebuffSkillType, type => type == (int)skillType); |
| | | } |
| | | |
| | | public MotionName GetMotionName() |
| | | { |
| | | return Enum.Parse<MotionName>(SkillMotionName); |
| | | } |
| | | |
| | | public static SkillConfig GetSkillConfig(int skillType, int skillLv) |
| | | { |
| | |
| | | return config; |
| | | } |
| | | |
| | | public List<int> GetDamageDivide(int _hitIndex) |
| | | { |
| | | List<int> damageDivide = new List<int>(); |
| | | if (_hitIndex == 0 && DamageDivide.Length <= 0) |
| | | { |
| | | damageDivide.Add(10000); |
| | | } |
| | | else |
| | | { |
| | | if (DamageDivide.Length <= _hitIndex) |
| | | { |
| | | Debug.LogError("技能伤害分布配置错误 skillId: " + SkillID + " hitIndex: " + _hitIndex); |
| | | damageDivide.Add(10000); |
| | | } |
| | | else |
| | | { |
| | | damageDivide = DamageDivide[_hitIndex].ToList(); |
| | | } |
| | | } |
| | | return damageDivide; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | //-------------------------------------------------------- |
| | | // [Author]: YYL |
| | | // [ Date ]: 2026年2月7日 |
| | | //-------------------------------------------------------- |
| | | |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Threading; |
| | | using System; |
| | | using UnityEngine; |
| | | using LitJson; |
| | | using System.Linq; |
| | | |
| | | |
| | | public partial class SkillSkinConfig : ConfigBase<string, SkillSkinConfig> |
| | | { |
| | | public SkillCastMode castMode; |
| | | |
| | | public SkillEffectType effectType; |
| | | |
| | | protected override void OnConfigParseCompleted() |
| | | { |
| | | base.OnConfigParseCompleted(); |
| | | |
| | | castMode = (SkillCastMode)CastPosition; |
| | | effectType = (SkillEffectType)EffectType; |
| | | |
| | | |
| | | if (DamageDivide == null || DamageDivide.Length == 0) |
| | | { |
| | | DamageDivide = new int[1][]; |
| | | DamageDivide[0] = new int[] { 10000 }; |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | public MotionName GetMotionName() |
| | | { |
| | | return Enum.Parse<MotionName>(SkillMotionName); |
| | | } |
| | | |
| | | public List<int> GetDamageDivide(int _hitIndex) |
| | | { |
| | | List<int> damageDivide = new List<int>(); |
| | | if (_hitIndex == 0 && DamageDivide.Length <= 0) |
| | | { |
| | | damageDivide.Add(10000); |
| | | } |
| | | else |
| | | { |
| | | if (DamageDivide.Length <= _hitIndex) |
| | | { |
| | | Debug.LogError("技能伤害分布配置错误 SkillSkinID: " + SkillSkinID + " hitIndex: " + _hitIndex); |
| | | damageDivide.Add(10000); |
| | | } |
| | | else |
| | | { |
| | | damageDivide = DamageDivide[_hitIndex].ToList(); |
| | | } |
| | | } |
| | | return damageDivide; |
| | | } |
| | | } |
| New file |
| | |
| | | fileFormatVersion: 2 |
| | | guid: 2e0292b891c625c45985eefa582a2463 |
| | | MonoImporter: |
| | | externalObjects: {} |
| | | serializedVersion: 2 |
| | | defaultReferences: [] |
| | | executionOrder: 0 |
| | | icon: {instanceID: 0} |
| | | userData: |
| | | assetBundleName: |
| | | assetBundleVariant: |
| | |
| | | if (hB427_TagSCUseSkill != null) |
| | | { |
| | | SkillConfig scCfg = SkillConfig.Get((int)hB427_TagSCUseSkill.SkillID); |
| | | if (!string.IsNullOrEmpty(scCfg.SkillMotionName)) |
| | | SkillSkinConfig skillSkinConfig = scCfg.GetOriginSkinConfig(); |
| | | if (!string.IsNullOrEmpty(skillSkinConfig.SkillMotionName)) |
| | | { |
| | | needWaiting = true; |
| | | return needWaiting; |
| | |
| | | if (pack is HB427_tagSCUseSkill skillPack && skillPack != hB427_TagSCUseSkill) |
| | | { |
| | | SkillConfig ssc = SkillConfig.Get((int)skillPack.SkillID); |
| | | if (!string.IsNullOrEmpty(ssc.SkillMotionName)) |
| | | SkillSkinConfig skillSkinConfig = ssc.GetOriginSkinConfig(); |
| | | if (!string.IsNullOrEmpty(skillSkinConfig.SkillMotionName)) |
| | | { |
| | | needWaiting = true; |
| | | break; |
| | |
| | | return GetTeamNode(battleCamp, index); |
| | | } |
| | | |
| | | public RectTransform GetTeamNode(BattleCamp battleCamp, SkillConfig skillConfig) |
| | | public RectTransform GetTeamNode(BattleCamp battleCamp, SkillSkinConfig skillSkinConfig) |
| | | { |
| | | int index = skillConfig.CastIndexNum - 1; // 技能配置的index是从1开始的,所以要减1 |
| | | int index = skillSkinConfig.CastIndexNum - 1; // 技能配置的index是从1开始的,所以要减1 |
| | | return GetTeamNode(battleCamp, index); |
| | | } |
| | | |
| | |
| | | if (isCast) |
| | | return; |
| | | |
| | | if (skillBase.caster.CanCastSkillAnimation(skillBase.skillConfig)) |
| | | if (skillBase.caster.CanCastSkillAnimation(skillBase.skillSkinConfig)) |
| | | { |
| | | // Debug.LogError("cast skill id is " + skillBase.skillConfig.SkillID); |
| | | |
| | |
| | | /// <summary> |
| | | /// 播放技能动画 |
| | | /// </summary> |
| | | public abstract Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillBase skillBase, bool isCounter, Action onComplete); |
| | | public abstract Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillSkinConfig skillSkinConfig, SkillBase skillBase, bool isCounter, Action onComplete); |
| | | |
| | | /// <summary> |
| | | /// 检查是否可以开始死亡 |
| | |
| | | /// <summary> |
| | | /// 检查是否可以释放技能 |
| | | /// </summary> |
| | | public abstract bool CanCastSkillAnimation(SkillConfig skillConfig); |
| | | public abstract bool CanCastSkillAnimation(SkillSkinConfig skillSkinConfig); |
| | | |
| | | /// <summary> |
| | | /// 获取骨骼动画组件(用于特效挂载等) |
| | |
| | | } |
| | | |
| | | // ============ 应用施法者的血量和护盾变化 ============ |
| | | bool isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillConfig.DamageDivide.Length - 1; |
| | | bool isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillSkinConfig.DamageDivide.Length - 1; |
| | | ApplyHurtToCaster(battleHurtParam, isLastHit); |
| | | |
| | | // 和Hurt一样,调用PopDamage处理吸血/反伤的显示 |
| | |
| | | Debug.LogError($"BattleObjectFactory: Failed to load SkeletonDataAsset for {skinCfg.SpineRes}"); |
| | | return null; |
| | | } |
| | | |
| | | Debug.LogError($"{teamHero.SkinID} : {skinCfg.SpineRes}"); |
| | | |
| | | // ============================================== |
| | | |
| | | GameObject battleGO = ResManager.Instance.LoadAsset<GameObject>("Hero/SpineRes", "Hero_001"/*skinCfg.SpineRes*/); |
| | |
| | | } |
| | | } |
| | | |
| | | public override Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillBase skillBase, bool isCounter, Action onComplete) |
| | | public override Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillSkinConfig skillSkinConfig, SkillBase skillBase, bool isCounter, Action onComplete) |
| | | { |
| | | return motionBase.PlaySkillAnimation(skillConfig, skillBase, isCounter, onComplete); |
| | | return motionBase.PlaySkillAnimation(skillConfig, skillSkinConfig, skillBase, isCounter, onComplete); |
| | | } |
| | | |
| | | public override bool CanStartDeath() |
| | |
| | | return motionBase.CanStartDeath(); |
| | | } |
| | | |
| | | public override bool CanCastSkillAnimation(SkillConfig skillConfig) |
| | | public override bool CanCastSkillAnimation(SkillSkinConfig skillSkinConfig) |
| | | { |
| | | return motionBase.CanCastSkill(skillConfig); |
| | | return motionBase.CanCastSkill(skillSkinConfig); |
| | | } |
| | | |
| | | public override SkeletonAnimation GetSkeletonAnimation() |
| | |
| | | public override DeathRecordAction Hurt(BattleHurtParam battleHurtParam, SkillRecordAction _parentSkillAction = null) |
| | | { |
| | | DeathRecordAction recordAction = null; |
| | | bool isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillConfig.DamageDivide.Length - 1; |
| | | bool isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillSkinConfig.DamageDivide.Length - 1; |
| | | bool firstHit = battleHurtParam.hitIndex == 0; |
| | | |
| | | // 添加调试日志 |
| | |
| | | } |
| | | |
| | | // ============ 应用施法者的血量和护盾变化 ============ |
| | | bool isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillConfig.DamageDivide.Length - 1; |
| | | bool isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillSkinConfig.DamageDivide.Length - 1; |
| | | ApplyHurtToCaster(battleHurtParam, isLastHit); |
| | | |
| | | // 和Hurt一样,调用PopDamage处理吸血/反伤的显示 |
| | |
| | | // 命格没有幻影 |
| | | } |
| | | |
| | | public override Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillBase skillBase, bool isCounter, Action onComplete) |
| | | public override Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillSkinConfig skillSkinConfig, SkillBase skillBase, bool isCounter, Action onComplete) |
| | | { |
| | | // 命格没有技能动画,立即触发所有帧事件 |
| | | int loopCount = skillConfig.LoopCount + 1; //默认会有一次 |
| | | int frameCount = skillConfig.ActiveFrames.Length; |
| | | int loopCount = skillSkinConfig.LoopCount + 1; //默认会有一次 |
| | | int frameCount = skillSkinConfig.ActiveFrames.Length; |
| | | |
| | | // 1. 技能开始 |
| | | skillBase.OnSkillStart(); |
| | |
| | | return false; |
| | | } |
| | | |
| | | public override bool CanCastSkillAnimation(SkillConfig skillConfig) |
| | | public override bool CanCastSkillAnimation(SkillSkinConfig skillSkinConfig) |
| | | { |
| | | // 命格总是可以释放技能(从动画角度) |
| | | return true; |
| | |
| | | // 普攻技能 |
| | | if (teamHero.heroConfig.AtkSkillID > 0) |
| | | { |
| | | AddSingleSkillResources(teamHero.heroConfig.AtkSkillID, info, isPersistent, ownerId); |
| | | SkillConfig skillConfig = SkillConfig.Get(teamHero.heroConfig.AtkSkillID); |
| | | if (null != skillConfig) |
| | | { |
| | | SkillSkinConfig skillSkinConfig = skillConfig.GetSkillSkinConfig(teamHero.SkinID); |
| | | if (null != skillSkinConfig) |
| | | { |
| | | AddSingleSkillResources(skillSkinConfig, info, isPersistent, ownerId); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 怒气技能 |
| | | if (teamHero.heroConfig.AngerSkillID > 0) |
| | | { |
| | | AddSingleSkillResources(teamHero.heroConfig.AngerSkillID, info, isPersistent, ownerId); |
| | | SkillConfig skillConfig = SkillConfig.Get(teamHero.heroConfig.AngerSkillID); |
| | | if (null != skillConfig) |
| | | { |
| | | SkillSkinConfig skillSkinConfig = skillConfig.GetSkillSkinConfig(teamHero.SkinID); |
| | | if (null != skillSkinConfig) |
| | | { |
| | | AddSingleSkillResources(skillSkinConfig, info, isPersistent, ownerId); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加单个技能的资源 |
| | | /// </summary> |
| | | private static void AddSingleSkillResources(int skillId, TeamResourceInfo info, bool isPersistent, string ownerId) |
| | | private static void AddSingleSkillResources(SkillSkinConfig skillSkinConfig, TeamResourceInfo info, bool isPersistent, string ownerId) |
| | | { |
| | | SkillConfig skillConfig = SkillConfig.Get(skillId); |
| | | if (skillConfig == null) |
| | | return; |
| | | |
| | | AddSkillAudio(skillConfig, info, isPersistent, ownerId); |
| | | AddSkillEffects(skillConfig, info, isPersistent, ownerId); |
| | | AddSkillAudio(skillSkinConfig, info, isPersistent, ownerId); |
| | | AddSkillEffects(skillSkinConfig, info, isPersistent, ownerId); |
| | | } |
| | | |
| | | private static void AddSkillAudio(SkillConfig skillConfig, TeamResourceInfo info, bool isPersistent, string ownerId) |
| | | private static void AddSkillAudio(SkillSkinConfig skillSkinConfig, TeamResourceInfo info, bool isPersistent, string ownerId) |
| | | { |
| | | if (skillConfig.SkinllSFX1 > 0) |
| | | if (skillSkinConfig.SkinllSFX1 > 0) |
| | | { |
| | | AddAudioResource(skillConfig.SkinllSFX1, info, isPersistent, ownerId); |
| | | AddAudioResource(skillSkinConfig.SkinllSFX1, info, isPersistent, ownerId); |
| | | } |
| | | |
| | | if (skillConfig.SkinllSFX2 > 0) |
| | | if (skillSkinConfig.SkinllSFX2 > 0) |
| | | { |
| | | AddAudioResource(skillConfig.SkinllSFX2, info, isPersistent, ownerId); |
| | | AddAudioResource(skillSkinConfig.SkinllSFX2, info, isPersistent, ownerId); |
| | | } |
| | | } |
| | | |
| | | private static void AddSkillEffects(SkillConfig skillConfig, TeamResourceInfo info, bool isPersistent, string ownerId) |
| | | private static void AddSkillEffects(SkillSkinConfig skillSkinConfig, TeamResourceInfo info, bool isPersistent, string ownerId) |
| | | { |
| | | List<int> effectIds = new List<int>(); |
| | | |
| | | if (skillConfig.BulletEffectId > 0) effectIds.Add(skillConfig.BulletEffectId); |
| | | if (skillConfig.ExplosionEffectId > 0) effectIds.Add(skillConfig.ExplosionEffectId); |
| | | if (skillConfig.ExplosionEffect2 > 0) effectIds.Add(skillConfig.ExplosionEffect2); |
| | | if (skillConfig.ExplosionEffect3 > 0) effectIds.Add(skillConfig.ExplosionEffect3); |
| | | if (skillConfig.ExplosionEffect4 > 0) effectIds.Add(skillConfig.ExplosionEffect4); |
| | | if (skillConfig.EffectId > 0) effectIds.Add(skillConfig.EffectId); |
| | | if (skillConfig.EffectId2 > 0) effectIds.Add(skillConfig.EffectId2); |
| | | if (skillConfig.MStartEffectId > 0) effectIds.Add(skillConfig.MStartEffectId); |
| | | if (skillConfig.BuffEffect > 0) effectIds.Add(skillConfig.BuffEffect); |
| | | if (skillConfig.TriggerEffect > 0) effectIds.Add(skillConfig.TriggerEffect); |
| | | if (skillSkinConfig.BulletEffectId > 0) effectIds.Add(skillSkinConfig.BulletEffectId); |
| | | if (skillSkinConfig.ExplosionEffectId > 0) effectIds.Add(skillSkinConfig.ExplosionEffectId); |
| | | if (skillSkinConfig.ExplosionEffect2 > 0) effectIds.Add(skillSkinConfig.ExplosionEffect2); |
| | | if (skillSkinConfig.ExplosionEffect3 > 0) effectIds.Add(skillSkinConfig.ExplosionEffect3); |
| | | if (skillSkinConfig.ExplosionEffect4 > 0) effectIds.Add(skillSkinConfig.ExplosionEffect4); |
| | | if (skillSkinConfig.EffectId > 0) effectIds.Add(skillSkinConfig.EffectId); |
| | | if (skillSkinConfig.EffectId2 > 0) effectIds.Add(skillSkinConfig.EffectId2); |
| | | if (skillSkinConfig.MStartEffectId > 0) effectIds.Add(skillSkinConfig.MStartEffectId); |
| | | if (skillSkinConfig.BuffEffect > 0) effectIds.Add(skillSkinConfig.BuffEffect); |
| | | if (skillSkinConfig.TriggerEffect > 0) effectIds.Add(skillSkinConfig.TriggerEffect); |
| | | |
| | | foreach (int effectId in effectIds) |
| | | { |
| | |
| | | { |
| | | long suckHp = GetSuckHp(skillBase.tagUseSkillAttack); |
| | | SkillConfig skillConfig = skillBase.skillConfig; |
| | | SkillSkinConfig skillSkinConfig = skillBase.skillSkinConfig; |
| | | long totalDamage = GeneralDefine.GetFactValue(hurt.HurtHP, hurt.HurtHPEx); |
| | | long totalReflectHp = hurt.BounceHP; |
| | | |
| | | // 计算伤害分段 |
| | | long currentHitDamage = 0; |
| | | List<long> damageList = DivideDamageToList(skillConfig.DamageDivide, hitIndex, totalDamage, ref currentHitDamage); |
| | | List<long> damageList = DivideDamageToList(skillSkinConfig.DamageDivide, hitIndex, totalDamage, ref currentHitDamage); |
| | | |
| | | // 计算吸血分段 |
| | | long currentHitSuckHp = 0; |
| | | List<long> suckHpList = bSuckHp ? |
| | | DivideDamageToList(skillConfig.DamageDivide, hitIndex, suckHp, ref currentHitSuckHp) : new List<long>(); |
| | | DivideDamageToList(skillSkinConfig.DamageDivide, hitIndex, suckHp, ref currentHitSuckHp) : new List<long>(); |
| | | |
| | | // 计算反伤分段 |
| | | long currentHitReflectHp = 0; |
| | | List<long> reflectHpList = DivideDamageToList(skillConfig.DamageDivide, hitIndex, totalReflectHp, ref currentHitReflectHp); |
| | | List<long> reflectHpList = DivideDamageToList(skillSkinConfig.DamageDivide, hitIndex, totalReflectHp, ref currentHitReflectHp); |
| | | |
| | | // 创建目标受伤对象 |
| | | BattleHurtObj hurter = CreateHurter(target, damageList, hurt, hitIndex, skillConfig, currentHitDamage); |
| | | BattleHurtObj hurter = CreateHurter(target, damageList, hurt, hitIndex, skillSkinConfig, currentHitDamage); |
| | | |
| | | // 创建施法者对象 |
| | | BattleCastObj caster = CreateCaster(skillBase, suckHpList, reflectHpList, currentHitSuckHp, currentHitReflectHp); |
| | |
| | | battleHurtParam.hitIndex = hitIndex; |
| | | battleHurtParam.deadPack = deadPack; |
| | | battleHurtParam.skillConfig = skillConfig; |
| | | battleHurtParam.skillSkinConfig = skillSkinConfig; |
| | | battleHurtParam.packUID = skillBase.tagUseSkillAttack.packUID; |
| | | return battleHurtParam; |
| | | } |
| | | |
| | | public static BattleHurtObj CreateHurter(BattleObject target, List<long> damageList, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, int hitIndex, SkillConfig skillConfig, long currentHitDamage) |
| | | public static BattleHurtObj CreateHurter(BattleObject target, List<long> damageList, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, int hitIndex, SkillSkinConfig skillSkinConfig, long currentHitDamage) |
| | | { |
| | | BattleHurtObj hurter = new BattleHurtObj(); |
| | | hurter.hurtObj = target; |
| | |
| | | hurter.fromShieldValue = buffMgr != null ? buffMgr.GetShieldValue() : 0; // 命格没有护盾 |
| | | |
| | | // 判断是否是最后一击 |
| | | bool isLastHit = hitIndex >= skillConfig.DamageDivide.Length - 1; |
| | | bool isLastHit = hitIndex >= skillSkinConfig.DamageDivide.Length - 1; |
| | | |
| | | // 判断是治疗还是伤害 |
| | | bool isHealing = IsHealing(hurt); |
| | |
| | | { |
| | | var skillID = hB427_TagSCUseSkill.SkillID; |
| | | var skillConfig = SkillConfig.Get((int)skillID); |
| | | var skillSkinConfig = skillConfig.GetOriginSkinConfig(); |
| | | |
| | | if (null == skillConfig) |
| | | { |
| | |
| | | { |
| | | HB428_tagSCBuffRefresh buffData = null; |
| | | |
| | | |
| | | bool isRemove = false; |
| | | |
| | | if (buffDataDict.TryGetValue(tempvNetData.BuffID, out buffData)) |
| | |
| | | return; |
| | | } |
| | | |
| | | BattleObject buffCaster = battleObject.battleField.battleObjMgr.GetBattleObject((int)buffData.OwnerID); |
| | | |
| | | if (null == buffCaster) |
| | | { |
| | | Debug.LogError("找不到buff caster 对象 id is " + buffData.OwnerID + " buff id is " + tempvNetData.BuffID + " pack uid is " + vNetData.packUID); |
| | | } |
| | | |
| | | bool isRemoveEffect = false; |
| | | |
| | | int remainCnt = -1; |
| | | |
| | | if (buffData != null) |
| | | if (buffData != null && buffCaster != null) |
| | | { |
| | | SkillConfig skillConfig = SkillConfig.Get((int)buffData.SkillID); |
| | | SkillSkinConfig skillSkinConfig = null; |
| | | if (buffCaster is HeroBattleObject heroBattleObject) |
| | | { |
| | | skillSkinConfig = skillConfig.GetSkillSkinConfig(heroBattleObject.teamHero.SkinID); |
| | | } |
| | | else |
| | | { |
| | | skillSkinConfig = skillConfig.GetOriginSkinConfig(); |
| | | } |
| | | |
| | | if (null == skillConfig || skillConfig.BuffEffect <= 0) |
| | | if (null == skillConfig || skillSkinConfig.BuffEffect <= 0) |
| | | { |
| | | return; |
| | | } |
| | | |
| | | KeyValuePair<BattleEffectPlayer, HashSet<uint>> effectPair; |
| | | |
| | | if (buffEffectDict.TryGetValue(skillConfig.BuffEffect, out effectPair)) |
| | | if (buffEffectDict.TryGetValue(skillSkinConfig.BuffEffect, out effectPair)) |
| | | { |
| | | effectPair.Value.Remove(buffData.BuffID); |
| | | |
| | |
| | | { |
| | | // 没有这个buff了 |
| | | isRemoveEffect = true; |
| | | battleObject.battleField.battleEffectMgr.RemoveEffect(skillConfig.BuffEffect, effectPair.Key); |
| | | buffEffectDict.Remove(skillConfig.BuffEffect); |
| | | battleObject.battleField.battleEffectMgr.RemoveEffect(skillSkinConfig.BuffEffect, effectPair.Key); |
| | | buffEffectDict.Remove(skillSkinConfig.BuffEffect); |
| | | } |
| | | } |
| | | |
| | |
| | | if (battleObject.IsDead()) |
| | | return; |
| | | |
| | | if (skillConfig.BuffEffect > 0) |
| | | BattleObject buffCaster = battleObject.battleField.battleObjMgr.GetBattleObject((int)buffRefresh.OwnerID); |
| | | |
| | | if (null == buffCaster) |
| | | { |
| | | if (buffEffectDict.TryGetValue(skillConfig.BuffEffect, out var pair)) |
| | | Debug.LogError("找不到buff caster 对象 id is " + buffRefresh.OwnerID + " buff id is " + buffRefresh.BuffID + " pack uid is " + buffRefresh.packUID); |
| | | } |
| | | |
| | | SkillSkinConfig skillSkinConfig = null; |
| | | |
| | | if (buffCaster is HeroBattleObject heroBattleObject) |
| | | { |
| | | skillSkinConfig = skillConfig.GetSkillSkinConfig(heroBattleObject.teamHero.SkinID); |
| | | } |
| | | else |
| | | { |
| | | skillSkinConfig = skillConfig.GetOriginSkinConfig(); |
| | | } |
| | | |
| | | |
| | | if (skillSkinConfig.BuffEffect > 0) |
| | | { |
| | | if (buffEffectDict.TryGetValue(skillSkinConfig.BuffEffect, out var pair)) |
| | | { |
| | | pair.Value.Add(buffRefresh.BuffID); |
| | | } |
| | | else |
| | | { |
| | | BattleEffectPlayer effect = battleObject.battleField.battleEffectMgr |
| | | .PlayEffect(battleObject, skillConfig.BuffEffect, battleObject.GetRectTransform(), battleObject.Camp, battleObject.GetModelScale()); |
| | | .PlayEffect(battleObject, skillSkinConfig.BuffEffect, battleObject.GetRectTransform(), battleObject.Camp, battleObject.GetModelScale()); |
| | | |
| | | effect.BindBone(battleObject, effect.effectConfig.nodeName); |
| | | |
| | | var buffIdSet = new HashSet<uint> { buffRefresh.BuffID }; |
| | | buffEffectDict.Add( |
| | | skillConfig.BuffEffect, |
| | | skillSkinConfig.BuffEffect, |
| | | new KeyValuePair<BattleEffectPlayer, HashSet<uint>>(effect, buffIdSet)); |
| | | } |
| | | } |
| | |
| | | this.battleFieldGuid = battleFieldGuid; |
| | | this.battleHurtParam = battleHurtParam; |
| | | this.isCasterView = _isCasterView; |
| | | this.isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillConfig.DamageDivide.Length - 1; |
| | | this.isLastHit = battleHurtParam.hitIndex >= battleHurtParam.skillSkinConfig.DamageDivide.Length - 1; |
| | | this.isFirstHit = battleHurtParam.hitIndex == 0; |
| | | |
| | | m_rawAttackType = hurt == null ? 0 : hurt.AttackTypes; |
| | |
| | | public int hitIndex; |
| | | public BattleDeadPack deadPack; |
| | | public SkillConfig skillConfig; |
| | | public SkillSkinConfig skillSkinConfig; |
| | | |
| | | public ulong packUID; |
| | | } |
| | |
| | | return true; |
| | | } |
| | | |
| | | public Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillBase skillBase, bool isSubSkill, Action onComplete = null) |
| | | public Spine.TrackEntry PlaySkillAnimation(SkillConfig skillConfig, SkillSkinConfig skillSkinConfig, SkillBase skillBase, bool isSubSkill, Action onComplete = null) |
| | | { |
| | | if (skillConfig == null) |
| | | { |
| | |
| | | } |
| | | |
| | | // 如果没有动画名称,使用无动画模式 |
| | | if (string.IsNullOrEmpty(skillConfig.SkillMotionName)) |
| | | if (string.IsNullOrEmpty(skillSkinConfig.SkillMotionName)) |
| | | { |
| | | PlaySkillNoAnim(skillConfig, skillBase, onComplete, isSubSkill); |
| | | PlaySkillNoAnim(skillConfig, skillSkinConfig, skillBase, onComplete, isSubSkill); |
| | | return null; |
| | | } |
| | | |
| | | Spine.Animation targetAnim = FindAnim(skillConfig.SkillMotionName); |
| | | Spine.Animation targetAnim = FindAnim(skillSkinConfig.SkillMotionName); |
| | | if (targetAnim == null) |
| | | { |
| | | skillBase.ForceFinished(); |
| | | return null; |
| | | } |
| | | |
| | | return ExecuteSkillAnim(skillConfig, skillBase, onComplete, targetAnim, true, isSubSkill); |
| | | return ExecuteSkillAnim(skillConfig, skillSkinConfig, skillBase, onComplete, targetAnim, true, isSubSkill); |
| | | } |
| | | |
| | | |
| | | private Spine.TrackEntry ExecuteSkillAnim(SkillConfig skillConfig, SkillBase skillBase, Action onComplete, |
| | | private Spine.TrackEntry ExecuteSkillAnim(SkillConfig skillConfig, SkillSkinConfig skillSkinConfig, SkillBase skillBase, Action onComplete, |
| | | Spine.Animation targetAnim, bool hasAnim, bool isSubSkill) |
| | | { |
| | | |
| | | int loopCount = skillConfig.LoopCount; |
| | | int loopCount = skillSkinConfig.LoopCount; |
| | | // 前摇 |
| | | int startupFrames = skillConfig.StartupFrames; |
| | | int startupFrames = skillSkinConfig.StartupFrames; |
| | | // 中摇 |
| | | int[] activeFrames = skillConfig.ActiveFrames ?? new int[0]; |
| | | int[] activeFrames = skillSkinConfig.ActiveFrames ?? new int[0]; |
| | | int frameCount = activeFrames.Length; |
| | | // 后摇 |
| | | float recoveryFrame = skillConfig.RecoveryFrames; |
| | | float recoveryFrame = skillSkinConfig.RecoveryFrames; |
| | | |
| | | // 如果前中后摇没有配置 那么默认给一个1 2 3的帧数 |
| | | if (startupFrames <= 0 && frameCount == 0 && recoveryFrame <= 0f) |
| | |
| | | { |
| | | // 轨道池耗尽或未初始化,回退到无动画模式 |
| | | Debug.LogWarning($"子技能轨道池已满或未初始化,技能{skillConfig.SkillID}使用无动画模式"); |
| | | PlaySkillNoAnim(skillConfig, skillBase, onComplete, isSubSkill); |
| | | PlaySkillNoAnim(skillConfig, skillSkinConfig, skillBase, onComplete, isSubSkill); |
| | | return null; |
| | | } |
| | | } |
| | |
| | | { |
| | | if (skillBase != null && !skillBase.IsFinished()) |
| | | { |
| | | PlaySkillAnimation(skillConfig, skillBase, isSubSkill, onComplete); |
| | | PlaySkillAnimation(skillConfig, skillSkinConfig, skillBase, isSubSkill, onComplete); |
| | | } |
| | | }); |
| | | return null; |
| | |
| | | } |
| | | |
| | | // 各阶段回调(原有逻辑) |
| | | if (!beginTriggered && currentFrame >= skillConfig.StartupFrames && currentLoop == 0) |
| | | if (!beginTriggered && currentFrame >= skillSkinConfig.StartupFrames && currentLoop == 0) |
| | | { |
| | | beginTriggered = true; |
| | | skillBase.OnStartSkillFrameEnd(); |
| | | } |
| | | |
| | | if (!middleStarted && currentFrame >= skillConfig.StartupFrames && currentLoop <= loopCount) |
| | | if (!middleStarted && currentFrame >= skillSkinConfig.StartupFrames && currentLoop <= loopCount) |
| | | { |
| | | middleStarted = true; |
| | | skillBase.OnMiddleFrameStart(currentLoop); |
| | |
| | | { |
| | | if (hasAnim) |
| | | { |
| | | skillTrack.TrackTime = skillConfig.StartupFrames / BattleConst.skillMotionFps; |
| | | skillTrack.TrackTime = skillSkinConfig.StartupFrames / BattleConst.skillMotionFps; |
| | | } |
| | | else |
| | | { |
| | | // 为下一 loop 重置 startTime,并且更新 pausedAccumulatedAtStart(以保持基线) |
| | | startTime = Time.time - (skillConfig.StartupFrames / BattleConst.skillMotionFps); |
| | | startTime = Time.time - (skillSkinConfig.StartupFrames / BattleConst.skillMotionFps); |
| | | pausedAccumulatedAtStart = pausedAccumulated; |
| | | } |
| | | } |
| | |
| | | return targetAnim; |
| | | } |
| | | |
| | | private void PlaySkillNoAnim(SkillConfig skillConfig, SkillBase skillBase, Action onComplete, bool isSubSkill) => |
| | | ExecuteSkillAnim(skillConfig, skillBase, onComplete, null, false, isSubSkill); |
| | | private void PlaySkillNoAnim(SkillConfig skillConfig, SkillSkinConfig skillSkinConfig, SkillBase skillBase, Action onComplete, bool isSubSkill) => |
| | | ExecuteSkillAnim(skillConfig, skillSkinConfig, skillBase, onComplete, null, false, isSubSkill); |
| | | |
| | | protected virtual void SetupAnimationHandlers() |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | public bool CanCastSkill(SkillConfig skillConfig) |
| | | public bool CanCastSkill(SkillSkinConfig skillSkinConfig) |
| | | { |
| | | return !playingSkillWithAnim || string.IsNullOrEmpty(skillConfig.SkillMotionName); |
| | | return !playingSkillWithAnim || string.IsNullOrEmpty(skillSkinConfig.SkillMotionName); |
| | | } |
| | | |
| | | public bool CanStartDeath() |
| | |
| | | protected SkillEffect skillEffect; |
| | | public HB427_tagSCUseSkill tagUseSkillAttack; |
| | | public SkillConfig skillConfig; |
| | | |
| | | public SkillSkinConfig skillSkinConfig; |
| | | protected bool isFinished = false; |
| | | protected BattleField battleField = null; // 战场 |
| | | protected RectTransform targetNode = null; // 目标节点 |
| | |
| | | tagUseSkillAttack = vNetData; |
| | | battleField = _battleField; |
| | | packList = _packList; |
| | | |
| | | if (_caster is HeroBattleObject heroBattleObject) |
| | | { |
| | | skillSkinConfig = skillConfig.GetSkillSkinConfig(heroBattleObject.teamHero.SkinID); |
| | | |
| | | if (null == skillSkinConfig) |
| | | { |
| | | Debug.LogError("找不到技能皮肤表 " + "skillId: " + skillConfig.SkillID + " skinId: " + heroBattleObject.teamHero.SkinID); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | skillSkinConfig = skillConfig.GetOriginSkinConfig(); |
| | | } |
| | | |
| | | |
| | | // 注册正在释放的技能 |
| | | if (battleField != null && caster != null) |
| | |
| | | // 命格释放技能时 teamHero 为 null,监听器会正确处理(已有 null 检查) |
| | | EventBroadcast.Instance.Broadcast<string, SkillConfig, TeamHero>(EventName.BATTLE_CAST_SKILL, guid, skillConfig, teamHero); |
| | | |
| | | if (skillConfig.SkinllSFX1 != 0) |
| | | if (skillSkinConfig.SkinllSFX1 != 0) |
| | | { |
| | | battleField.soundManager.PlayEffectSound(skillConfig.SkinllSFX1, false); |
| | | battleField.soundManager.PlayEffectSound(skillSkinConfig.SkinllSFX1, false); |
| | | } |
| | | |
| | | if (caster != null) |
| | |
| | | HighLightAllTargets(); |
| | | |
| | | // 根据释放模式执行相应逻辑 |
| | | switch (skillConfig.castMode) |
| | | switch (skillSkinConfig.castMode) |
| | | { |
| | | case SkillCastMode.None: |
| | | case SkillCastMode.Self: |
| | |
| | | DashCast(OnAttackFinish); |
| | | break; |
| | | default: |
| | | Debug.LogError("强制结束技能 暂时不支持其他的方式释放 有需求please联系策划 技能id:" + skillConfig.SkillID + " cast position " + skillConfig.CastPosition); |
| | | Debug.LogError("强制结束技能 暂时不支持其他的方式释放 有需求please联系策划 技能id:" + skillConfig.SkillID + " cast position " + skillSkinConfig.CastPosition); |
| | | ForceFinished(); |
| | | break; |
| | | } |
| | |
| | | // 对敌方释放技能:移动到敌方区域进行攻击 |
| | | protected void CastToEnemy() |
| | | { |
| | | RectTransform target = battleField.GetTeamNode(caster.GetEnemyCamp(), skillConfig); |
| | | RectTransform target = battleField.GetTeamNode(caster.GetEnemyCamp(), skillSkinConfig); |
| | | ExecuteMoveAndCastSequence(target, () => |
| | | { |
| | | if (skillConfig.ClientTriggerTiming == 1) |
| | |
| | | // 对友方释放技能:移动到友方区域进行治疗或增益 |
| | | protected void CastToAllies() |
| | | { |
| | | RectTransform target = battleField.GetTeamNode(caster.Camp, skillConfig); |
| | | RectTransform target = battleField.GetTeamNode(caster.Camp, skillSkinConfig); |
| | | ExecuteMoveAndCastSequence(target, () => |
| | | { |
| | | if (skillConfig.ClientTriggerTiming == 1) |
| | |
| | | private void ExecuteMoveAndCastSequence(RectTransform target, Action onReturnComplete) |
| | | { |
| | | ShadowIllutionCreate(true); |
| | | MoveToTarget(target, new Vector2(skillConfig.CastDistance, 0), () => |
| | | MoveToTarget(target, new Vector2(skillSkinConfig.CastDistance, 0), () => |
| | | { |
| | | if (skillConfig.CastDistance < 9999 && skillConfig.SkinllSFX2 != 0) |
| | | if (skillSkinConfig.CastDistance < 9999 && skillSkinConfig.SkinllSFX2 != 0) |
| | | { |
| | | battleField.soundManager.PlayEffectSound(skillConfig.SkinllSFX2, false); |
| | | battleField.soundManager.PlayEffectSound(skillSkinConfig.SkinllSFX2, false); |
| | | } |
| | | |
| | | TurnBack(() => |
| | |
| | | // 移动到目标位置:处理角色的移动动画和逻辑 |
| | | protected void MoveToTarget(RectTransform target, Vector2 offset, Action _onComplete = null, float speed = 750f) |
| | | { |
| | | if (skillConfig.CastDistance >= 9999) |
| | | if (skillSkinConfig.CastDistance >= 9999) |
| | | { |
| | | _onComplete?.Invoke(); |
| | | return; |
| | |
| | | // 转身逻辑:根据技能配置处理角色转向 |
| | | protected void TurnBack(Action _onComplete, float forward) |
| | | { |
| | | if (skillConfig.CastDistance < 0) |
| | | if (skillSkinConfig.CastDistance < 0) |
| | | { |
| | | caster.SetFacing(forward); |
| | | } |
| | |
| | | // 执行技能释放动画和逻辑:播放施法动作并提供回调 |
| | | protected TrackEntry CastImpl(Action onComplete = null) |
| | | { |
| | | return caster.PlaySkillAnimation(skillConfig, this, tagUseSkillAttack.BattleType == 4, onComplete); |
| | | return caster.PlaySkillAnimation(skillConfig, skillSkinConfig, this, tagUseSkillAttack.BattleType == 4, onComplete); |
| | | } |
| | | |
| | | // 技能开始回调:处理死亡、子技能、技能效果初始化 |
| | |
| | | // 再处理 内嵌技能 |
| | | ProcessSubSkill(); |
| | | |
| | | skillEffect = SkillEffectFactory.CreateSkillEffect(this, caster, skillConfig, tagUseSkillAttack); |
| | | skillEffect = SkillEffectFactory.CreateSkillEffect(this, caster, skillConfig, skillSkinConfig, tagUseSkillAttack); |
| | | skillEffect.Play(OnHitTargets); |
| | | |
| | | |
| | |
| | | if (pack is HB427_tagSCUseSkill skillPack) |
| | | { |
| | | SkillConfig ssc = SkillConfig.Get((int)skillPack.SkillID); |
| | | if (!string.IsNullOrEmpty(ssc.SkillMotionName)) |
| | | SkillSkinConfig sscSkin = ssc.GetOriginSkinConfig(); |
| | | if (!string.IsNullOrEmpty(sscSkin.SkillMotionName)) |
| | | { |
| | | break; |
| | | } |
| | |
| | | { |
| | | HB427_tagSCUseSkill sp = combinePack.GetMainHB427SkillPack(); |
| | | SkillConfig ssc = SkillConfig.Get((int)sp.SkillID); |
| | | |
| | | if (!string.IsNullOrEmpty(ssc.SkillMotionName)) |
| | | SkillSkinConfig sscSkin = ssc.GetOriginSkinConfig(); |
| | | if (!string.IsNullOrEmpty(sscSkin.SkillMotionName)) |
| | | { |
| | | break; |
| | | } |
| | |
| | | #if UNITY_EDITOR |
| | | private void PrintHurtParamDebugInfo(BattleHurtParam hurtParam) |
| | | { |
| | | bool isLastHit = hurtParam.hitIndex >= hurtParam.skillConfig.DamageDivide.Length - 1; |
| | | bool isLastHit = hurtParam.hitIndex >= hurtParam.skillSkinConfig.DamageDivide.Length - 1; |
| | | |
| | | long currentHitDamage = hurtParam.hurter.damageList != null ? hurtParam.hurter.damageList.Sum() : 0; |
| | | long currentHitSuckHp = hurtParam.caster.suckHpList != null ? hurtParam.caster.suckHpList.Sum() : 0; |
| | |
| | | $"攻击者: {hurtParam.caster.casterObj.GetName()} (ObjID:{hurtParam.caster.casterObj.ObjID})\n" + |
| | | $"目标: {hurtParam.hurter.hurtObj.GetName()} (ObjID:{hurtParam.hurter.hurtObj.ObjID})\n" + |
| | | $"技能: {hurtParam.skillConfig.SkillName} (ID:{hurtParam.skillConfig.SkillID})\n" + |
| | | $"击数: 第{hurtParam.hitIndex + 1}击 / 共{hurtParam.skillConfig.DamageDivide.Length}击" + (isLastHit ? " [最后一击]" : " [中间击]") + "\n" + |
| | | $"击数: 第{hurtParam.hitIndex + 1}击 / 共{hurtParam.skillSkinConfig.DamageDivide.Length}击" + (isLastHit ? " [最后一击]" : " [中间击]") + "\n" + |
| | | $"\n" + |
| | | $"========== 目标受伤数据 ==========\n" + |
| | | $"伤害: {currentHitDamage} / 总伤害: {totalDamage}\n" + |
| | |
| | | if (moveFinished) |
| | | { |
| | | // 如果技能有动画(SkillMotionName不为空),需要等待动画播放完成 |
| | | if (skillConfig != null && !string.IsNullOrEmpty(skillConfig.SkillMotionName)) |
| | | if (skillSkinConfig != null && !string.IsNullOrEmpty(skillSkinConfig.SkillMotionName)) |
| | | { |
| | | if (!isMotionCompleted) |
| | | { |
| | |
| | | return false; |
| | | } |
| | | |
| | | if (string.IsNullOrEmpty(skillConfig.SkillMotionName)) |
| | | if (string.IsNullOrEmpty(skillSkinConfig.SkillMotionName)) |
| | | { |
| | | return true; |
| | | } |
| | |
| | | private Vector2 end; |
| | | private Vector2 control; |
| | | |
| | | public BezierBulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer effectPlayer, |
| | | public BezierBulletCurve(BattleObject caster, SkillConfig skillConfig, SkillSkinConfig _skillSkinConfig, BattleEffectPlayer effectPlayer, |
| | | RectTransform target, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hurtList, int bulletIndex, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit) |
| | | : base(caster, skillConfig, effectPlayer, target, hurtList, bulletIndex, onHit) { } |
| | | : base(caster, skillConfig, _skillSkinConfig, effectPlayer, target, hurtList, bulletIndex, onHit) { } |
| | | |
| | | public override void Reset() |
| | | { |
| | | base.Reset(); |
| | | start = WorldToLocalAnchoredPosition(bulletTrans.position) + bulletOffset; |
| | | end = WorldToLocalAnchoredPosition(target.position); |
| | | duration = Vector2.Distance(start, end) / skillConfig.BulletFlySpeed; |
| | | duration = Vector2.Distance(start, end) / skillSkinConfig.BulletFlySpeed; |
| | | control = (start + end) / 2 + Vector2.up * 100f; |
| | | } |
| | | |
| | |
| | | private float bounceTime = 0.2f; // 每次弹射时间 |
| | | private float bounceElapsed = 0f; |
| | | |
| | | public BounceBulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer effectPlayer, |
| | | public BounceBulletCurve(BattleObject caster, SkillConfig skillConfig, SkillSkinConfig _skillSkinConfig, BattleEffectPlayer effectPlayer, |
| | | RectTransform target, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hurtList, int bulletIndex, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit) |
| | | : base(caster, skillConfig, effectPlayer, target, hurtList, bulletIndex, onHit) |
| | | : base(caster, skillConfig, _skillSkinConfig, effectPlayer, target, hurtList, bulletIndex, onHit) |
| | | { |
| | | this.hurtList = hurtList; |
| | | } |
| | |
| | | { |
| | | start = WorldToLocalAnchoredPosition(bulletTrans.position) + bulletOffset; |
| | | end = WorldToLocalAnchoredPosition(target.position); |
| | | duration = Vector2.Distance(start, end) / skillConfig.BulletFlySpeed; |
| | | duration = Vector2.Distance(start, end) / skillSkinConfig.BulletFlySpeed; |
| | | } |
| | | } |
| | | |
| | |
| | | { |
| | | protected BattleObject caster; |
| | | protected SkillConfig skillConfig; |
| | | |
| | | protected SkillSkinConfig skillSkinConfig; |
| | | protected BattleEffectPlayer bulletEffect; |
| | | protected RectTransform bulletTrans; // 子弹的RectTransform |
| | | protected RectTransform target; |
| | |
| | | |
| | | protected List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hurts = new List<HB427_tagSCUseSkill.tagSCUseSkillHurt>(); |
| | | |
| | | public BulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer bulletEffect, RectTransform target, |
| | | public BulletCurve(BattleObject caster, SkillConfig skillConfig, SkillSkinConfig _skillSkinConfig, BattleEffectPlayer bulletEffect, RectTransform target, |
| | | List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hurtList, int bulletIndex, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit) |
| | | { |
| | | this.caster = caster; |
| | | this.skillConfig = skillConfig; |
| | | skillSkinConfig = _skillSkinConfig; |
| | | this.bulletEffect = bulletEffect; |
| | | this.target = target; |
| | | this.onHit = onHit; |
| | |
| | | { |
| | | finished = true; |
| | | onHit?.Invoke(mBulletIndex, hurts); |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, bulletEffect); |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillSkinConfig.BulletEffectId, bulletEffect); |
| | | } |
| | | |
| | | public virtual void ForceFinish() |
| | |
| | | public static BulletCurve CreateBulletCurve( |
| | | BattleObject caster, |
| | | SkillConfig skillConfig, |
| | | SkillSkinConfig _skillSkinConfig, |
| | | BattleEffectPlayer bulletEffect, |
| | | RectTransform target, |
| | | List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hurtList, |
| | |
| | | Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit) |
| | | { |
| | | BulletCurve curve = null; |
| | | switch (skillConfig.BulletPath) |
| | | switch (_skillSkinConfig.BulletPath) |
| | | { |
| | | case 1: // 直线消失于目标 |
| | | curve = new StraightBulletCurve(caster, skillConfig, bulletEffect, target, hurtList, bulletIndex, onHit); |
| | | curve = new StraightBulletCurve(caster, skillConfig, _skillSkinConfig, bulletEffect, target, hurtList, bulletIndex, onHit); |
| | | break; |
| | | case 2: // 直线贯穿消失在屏幕外 |
| | | curve = new PenetrateBulletCurve(caster, skillConfig, bulletEffect, target, hurtList, bulletIndex, onHit); |
| | | curve = new PenetrateBulletCurve(caster, skillConfig, _skillSkinConfig, bulletEffect, target, hurtList, bulletIndex, onHit); |
| | | break; |
| | | case 3: // 抛物线弧线 |
| | | curve = new BezierBulletCurve(caster, skillConfig, bulletEffect, target, hurtList, bulletIndex, onHit); |
| | | curve = new BezierBulletCurve(caster, skillConfig, _skillSkinConfig, bulletEffect, target, hurtList, bulletIndex, onHit); |
| | | break; |
| | | case 4: // 弹射 |
| | | curve = new BounceBulletCurve(caster, skillConfig, bulletEffect, target, hurtList, bulletIndex, onHit); |
| | | curve = new BounceBulletCurve(caster, skillConfig, _skillSkinConfig, bulletEffect, target, hurtList, bulletIndex, onHit); |
| | | break; |
| | | default: |
| | | curve = new BulletCurve(caster, skillConfig, bulletEffect, target, hurtList, bulletIndex, onHit); |
| | | curve = new BulletCurve(caster, skillConfig, _skillSkinConfig, bulletEffect, target, hurtList, bulletIndex, onHit); |
| | | break; |
| | | } |
| | | |
| | |
| | | private Vector2 outPos; // 屏幕外延长点(本地坐标) |
| | | private bool hitTriggered = false; // 是否已触发onHit |
| | | |
| | | public PenetrateBulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer effectPlayer, RectTransform target, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hurtList, int bulletIndex, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit) |
| | | : base(caster, skillConfig, effectPlayer, target, hurtList, bulletIndex, onHit) { } |
| | | public PenetrateBulletCurve(BattleObject caster, SkillConfig skillConfig, SkillSkinConfig _skillSkinConfig, BattleEffectPlayer effectPlayer, RectTransform target, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hurtList, int bulletIndex, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit) |
| | | : base(caster, skillConfig, _skillSkinConfig, effectPlayer, target, hurtList, bulletIndex, onHit) { } |
| | | |
| | | /// <summary> |
| | | /// 初始化弹道参数 |
| | |
| | | hitTriggered = false; |
| | | start = WorldToLocalAnchoredPosition(bulletTrans.position) + bulletOffset; |
| | | end = WorldToLocalAnchoredPosition(target.position); |
| | | duration = Vector2.Distance(start, end) / skillConfig.BulletFlySpeed; |
| | | duration = Vector2.Distance(start, end) / skillSkinConfig.BulletFlySpeed; |
| | | Vector2 dir = (end - start).normalized; |
| | | float extend = 500f; // 贯穿距离,可根据需求调整 |
| | | outPos = end + dir * extend; |
| | |
| | | private Vector2 start; |
| | | private Vector2 end; |
| | | |
| | | public StraightBulletCurve(BattleObject caster, SkillConfig skillConfig, BattleEffectPlayer bulletEffect, RectTransform target, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hurtList, int bulletIndex, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit) |
| | | : base(caster, skillConfig, bulletEffect, target, hurtList, bulletIndex, onHit) |
| | | public StraightBulletCurve(BattleObject caster, SkillConfig skillConfig, SkillSkinConfig _skillSkinConfig, BattleEffectPlayer bulletEffect, RectTransform target, List<HB427_tagSCUseSkill.tagSCUseSkillHurt> hurtList, int bulletIndex, Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit) |
| | | : base(caster, skillConfig, _skillSkinConfig, bulletEffect, target, hurtList, bulletIndex, onHit) |
| | | { |
| | | |
| | | } |
| | |
| | | base.Reset(); |
| | | start = WorldToLocalAnchoredPosition(bulletTrans.position) + bulletOffset; |
| | | end = WorldToLocalAnchoredPosition(target.position); |
| | | duration = Vector2.Distance(start, end) / skillConfig.BulletFlySpeed; |
| | | duration = Vector2.Distance(start, end) / skillSkinConfig.BulletFlySpeed; |
| | | // BattleUtility.MarkStartAndEnd(bulletTrans, target); |
| | | } |
| | | |
| | |
| | | private int scatterTotalTargets = 0; |
| | | |
| | | |
| | | public BulletSkillEffect(SkillBase _skillBase, SkillConfig _skillConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack) |
| | | : base(_skillBase, _skillConfig, _caster, _tagUseSkillAttack) |
| | | public BulletSkillEffect(SkillBase _skillBase, SkillConfig _skillConfig, SkillSkinConfig _skillSkinConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack) |
| | | : base(_skillBase, _skillConfig, _skillSkinConfig, _caster, _tagUseSkillAttack) |
| | | { |
| | | |
| | | } |
| | |
| | | { |
| | | base.OnMiddleFrameEnd(times, index); |
| | | // 弹射 另外的做法了 |
| | | if (skillConfig.effectType == SkillEffectType.Bullet && skillConfig.BulletPath == 4) |
| | | if (skillSkinConfig.effectType == SkillEffectType.Bullet && skillSkinConfig.BulletPath == 4) |
| | | { |
| | | var hurt = tagUseSkillAttack.HurtList[0]; |
| | | BattleObject targetObject = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID); |
| | |
| | | private void ShotToIndex(BattleCamp camp, int targetIndex, int bulletIndex) |
| | | { |
| | | RectTransform targetTransform = caster.battleField.GetTeamNode(camp, targetIndex); |
| | | BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.BulletEffectId, caster.GetRectTransform(), caster.Camp, caster.GetModelScale()); |
| | | BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.BulletEffectId, caster.GetRectTransform(), caster.Camp, caster.GetModelScale()); |
| | | |
| | | RectTransform effectTrans = effectPlayer.transform as RectTransform; |
| | | |
| | | var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, targetTransform, tagUseSkillAttack.HurtList.ToList(), bulletIndex, (index, hitList) => |
| | | var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, skillSkinConfig, effectPlayer, targetTransform, tagUseSkillAttack.HurtList.ToList(), bulletIndex, (index, hitList) => |
| | | { |
| | | if (isFinish) |
| | | return; |
| | | // 击中就销毁子弹 |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer); |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillSkinConfig.BulletEffectId, effectPlayer); |
| | | // 播放子弹爆炸特效 |
| | | |
| | | BattleCamp battleCamp = skillConfig.TagFriendly != 0 ? caster.Camp : caster.GetEnemyCamp(); |
| | | // 首先是目标身上爆炸 |
| | | PlayExplosionEffect(skillConfig.ExplosionEffectId, targetTransform, caster.Camp, 1f); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect2, targetTransform, caster.Camp, 1f); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffectId, targetTransform, caster.Camp, 1f); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect2, targetTransform, caster.Camp, 1f); |
| | | |
| | | foreach (var hurt in hitList) |
| | | { |
| | |
| | | continue; |
| | | } |
| | | |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect3, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect4, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect3, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect4, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | } |
| | | |
| | | // 表现子弹飞行到目标位置 |
| | |
| | | { |
| | | scatterHitCount = 0; |
| | | // 总击中数 = 发射次数 × 目标数量 |
| | | scatterTotalTargets = skillConfig.ActiveFrames.Length * tagUseSkillAttack.HurtList.Length; |
| | | scatterTotalTargets = skillSkinConfig.ActiveFrames.Length * tagUseSkillAttack.HurtList.Length; |
| | | } |
| | | |
| | | // 处理散射逻辑 |
| | |
| | | |
| | | private void ScatterShot(BattleObject target, HB427_tagSCUseSkill.tagSCUseSkillHurt hurt, int bulletIndex, int order) |
| | | { |
| | | BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.BulletEffectId, caster.GetRectTransform(), caster.Camp, caster.GetModelScale()); |
| | | BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.BulletEffectId, caster.GetRectTransform(), caster.Camp, caster.GetModelScale()); |
| | | |
| | | bool shotToSelf = target.ObjID == caster.ObjID; |
| | | |
| | |
| | | |
| | | var tempOrder = order; |
| | | |
| | | var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, target.GetRectTransform(), |
| | | var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, skillSkinConfig, effectPlayer, target.GetRectTransform(), |
| | | new List<HB427_tagSCUseSkill.tagSCUseSkillHurt> { hurt }, bulletIndex, (index, hitList) => |
| | | { |
| | | foreach (var hurt in hitList) |
| | |
| | | continue; |
| | | } |
| | | |
| | | PlayExplosionEffect(skillConfig.ExplosionEffectId, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect2, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect3, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect4, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffectId, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect2, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect3, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect4, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | } |
| | | |
| | | // 表现子弹飞行到目标位置 |
| | | onHit?.Invoke(index, hitList); |
| | | // 击中就销毁子弹 |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer); |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillSkinConfig.BulletEffectId, effectPlayer); |
| | | |
| | | // 增加散射击中计数 |
| | | scatterHitCount++; |
| | |
| | | |
| | | protected void ShotToTarget(BattleObject target, int bulletIndex) |
| | | { |
| | | BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.BulletEffectId, caster.GetRectTransform(), caster.Camp, caster.GetModelScale()); |
| | | BattleEffectPlayer effectPlayer = caster.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.BulletEffectId, caster.GetRectTransform(), caster.Camp, caster.GetModelScale()); |
| | | |
| | | bool shotToSelf = target.ObjID == caster.ObjID; |
| | | |
| | |
| | | |
| | | int tempBulletIndex = bulletIndex; |
| | | |
| | | var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, effectPlayer, target.GetRectTransform(), tagUseSkillAttack.HurtList.ToList(), bulletIndex, (index, hitList) => |
| | | var bulletCurve = BulletCurveFactory.CreateBulletCurve(caster, skillConfig, skillSkinConfig, effectPlayer, target.GetRectTransform(), tagUseSkillAttack.HurtList.ToList(), bulletIndex, (index, hitList) => |
| | | { |
| | | if (skillConfig.BulletPath == 4) |
| | | if (skillSkinConfig.BulletPath == 4) |
| | | { |
| | | if (bounceHitIndex >= hitList.Count) |
| | | { |
| | |
| | | BattleObject targetObj = caster.battleField.battleObjMgr.GetBattleObject((int)hurt.ObjID); |
| | | if (targetObj != null) |
| | | { |
| | | PlayExplosionEffect(skillConfig.ExplosionEffectId, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect2, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect3, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect4, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffectId, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect2, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect3, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect4, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | } |
| | | else |
| | | { |
| | |
| | | |
| | | if (bounceHitIndex >= tagUseSkillAttack.HurtList.Length) |
| | | { |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer); |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillSkinConfig.BulletEffectId, effectPlayer); |
| | | } |
| | | |
| | | if (isFinish) |
| | | return; |
| | | |
| | | if (tempBulletIndex >= skillConfig.ActiveFrames.Length - 1 && bounceHitIndex >= hitList.Count) |
| | | if (tempBulletIndex >= skillSkinConfig.ActiveFrames.Length - 1 && bounceHitIndex >= hitList.Count) |
| | | { |
| | | isFinish = true; |
| | | } |
| | |
| | | continue; |
| | | } |
| | | |
| | | PlayExplosionEffect(skillConfig.ExplosionEffectId, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect2, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect3, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillConfig.ExplosionEffect4, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffectId, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect2, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect3, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | PlayExplosionEffect(skillSkinConfig.ExplosionEffect4, targetObj.GetTransform(), caster.Camp, targetObj.GetModelScale()); |
| | | } |
| | | |
| | | // 表现子弹飞行到目标位置 |
| | | onHit?.Invoke(index, hitList); |
| | | // 击中就销毁子弹 |
| | | |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillConfig.BulletEffectId, effectPlayer); |
| | | caster.battleField.battleEffectMgr.RemoveEffect(skillSkinConfig.BulletEffectId, effectPlayer); |
| | | |
| | | if (isFinish) |
| | | return; |
| | | |
| | | if (bulletIndex >= skillConfig.ActiveFrames.Length - 1) |
| | | if (bulletIndex >= skillSkinConfig.ActiveFrames.Length - 1) |
| | | { |
| | | isFinish = true; |
| | | } |
| | |
| | | // protected BattleObject caster; |
| | | // protected List<BattleObject> targets; // 目标列表 |
| | | |
| | | public DotSkillEffect(SkillBase _skillBase, SkillConfig _skillConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack) |
| | | : base(_skillBase, _skillConfig, _caster, _tagUseSkillAttack) |
| | | public DotSkillEffect(SkillBase _skillBase, SkillConfig _skillConfig, SkillSkinConfig _skillSkinConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack) |
| | | : base(_skillBase, _skillConfig, _skillSkinConfig, _caster, _tagUseSkillAttack) |
| | | { |
| | | |
| | | } |
| | |
| | | Debug.LogError($"DotSkillEffect 找不到目标,GUID={hurtInfo.ObjID}"); |
| | | continue; |
| | | } |
| | | target.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.TriggerEffect, target.GetRectTransform(), caster.Camp, target.GetModelScale()); |
| | | target.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.TriggerEffect, target.GetRectTransform(), caster.Camp, target.GetModelScale()); |
| | | } |
| | | |
| | | onHit?.Invoke(0, tagUseSkillAttack.HurtList.ToList()); |
| | |
| | | // protected BattleObject caster; |
| | | // protected List<BattleObject> targets; // 目标列表 |
| | | |
| | | public NoEffect(SkillBase _skillBase, SkillConfig _skillConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack) |
| | | : base(_skillBase, _skillConfig, _caster, _tagUseSkillAttack) |
| | | public NoEffect(SkillBase _skillBase, SkillConfig _skillConfig, SkillSkinConfig _skillSkinConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack) |
| | | : base(_skillBase, _skillConfig, _skillSkinConfig, _caster, _tagUseSkillAttack) |
| | | { |
| | | |
| | | } |
| | |
| | | |
| | | RectTransform targetTransform = caster.battleField.GetTeamNode(battleCamp, mainTargetIndex); |
| | | |
| | | if (skillConfig.ExplosionEffectId > 0) |
| | | if (skillSkinConfig.ExplosionEffectId > 0) |
| | | { |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.ExplosionEffectId, targetTransform, caster.Camp, 1f); |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.ExplosionEffectId, targetTransform, caster.Camp, 1f); |
| | | } |
| | | |
| | | if (skillConfig.ExplosionEffect2 > 0) |
| | | if (skillSkinConfig.ExplosionEffect2 > 0) |
| | | { |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.ExplosionEffect2, targetTransform, caster.Camp, 1f); |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.ExplosionEffect2, targetTransform, caster.Camp, 1f); |
| | | } |
| | | |
| | | for (int i = 0; i < tagUseSkillAttack.HurtList.Length; i++) |
| | |
| | | continue; |
| | | } |
| | | |
| | | if (skillConfig.ExplosionEffect3 > 0) |
| | | if (skillSkinConfig.ExplosionEffect3 > 0) |
| | | { |
| | | caster.battleField.battleEffectMgr.PlayEffect(target, skillConfig.ExplosionEffect3, target.GetTransform(), caster.Camp, target.GetModelScale()); |
| | | caster.battleField.battleEffectMgr.PlayEffect(target, skillSkinConfig.ExplosionEffect3, target.GetTransform(), caster.Camp, target.GetModelScale()); |
| | | } |
| | | if (skillConfig.ExplosionEffect4 > 0) |
| | | if (skillSkinConfig.ExplosionEffect4 > 0) |
| | | { |
| | | caster.battleField.battleEffectMgr.PlayEffect(target, skillConfig.ExplosionEffect4, target.GetTransform(), caster.Camp, target.GetModelScale()); |
| | | caster.battleField.battleEffectMgr.PlayEffect(target, skillSkinConfig.ExplosionEffect4, target.GetTransform(), caster.Camp, target.GetModelScale()); |
| | | } |
| | | } |
| | | |
| | |
| | | // protected BattleObject caster; |
| | | // protected List<BattleObject> targets; // 目标列表 |
| | | |
| | | public NormalSkillEffect(SkillBase _skillBase, SkillConfig _skillConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack) |
| | | : base(_skillBase, _skillConfig, _caster, _tagUseSkillAttack) |
| | | public NormalSkillEffect(SkillBase _skillBase, SkillConfig _skillConfig, SkillSkinConfig _skillSkinConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack) |
| | | : base(_skillBase, _skillConfig, _skillSkinConfig, _caster, _tagUseSkillAttack) |
| | | { |
| | | |
| | | } |
| | |
| | | |
| | | RectTransform targetTransform = caster.battleField.GetTeamNode(battleCamp, mainTargetIndex); |
| | | |
| | | if (skillConfig.ExplosionEffectId > 0) |
| | | if (skillSkinConfig.ExplosionEffectId > 0) |
| | | { |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.ExplosionEffectId, targetTransform, caster.Camp, 1f); |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.ExplosionEffectId, targetTransform, caster.Camp, 1f); |
| | | } |
| | | |
| | | if (skillConfig.ExplosionEffect2 > 0) |
| | | if (skillSkinConfig.ExplosionEffect2 > 0) |
| | | { |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.ExplosionEffect2, targetTransform, caster.Camp, 1f); |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.ExplosionEffect2, targetTransform, caster.Camp, 1f); |
| | | } |
| | | |
| | | for (int i = 0; i < tagUseSkillAttack.HurtList.Length; i++) |
| | |
| | | continue; |
| | | } |
| | | |
| | | if (skillConfig.ExplosionEffect3 > 0) |
| | | if (skillSkinConfig.ExplosionEffect3 > 0) |
| | | { |
| | | caster.battleField.battleEffectMgr.PlayEffect(target, skillConfig.ExplosionEffect3, target.GetTransform(), caster.Camp, target.GetModelScale()); |
| | | caster.battleField.battleEffectMgr.PlayEffect(target, skillSkinConfig.ExplosionEffect3, target.GetTransform(), caster.Camp, target.GetModelScale()); |
| | | } |
| | | if (skillConfig.ExplosionEffect4 > 0) |
| | | if (skillSkinConfig.ExplosionEffect4 > 0) |
| | | { |
| | | caster.battleField.battleEffectMgr.PlayEffect(target, skillConfig.ExplosionEffect4, target.GetTransform(), caster.Camp, target.GetModelScale()); |
| | | caster.battleField.battleEffectMgr.PlayEffect(target, skillSkinConfig.ExplosionEffect4, target.GetTransform(), caster.Camp, target.GetModelScale()); |
| | | } |
| | | } |
| | | |
| | |
| | | { |
| | | protected SkillBase skillBase; |
| | | protected SkillConfig skillConfig; |
| | | protected SkillSkinConfig skillSkinConfig; |
| | | protected BattleObject caster; |
| | | protected HB427_tagSCUseSkill tagUseSkillAttack;// 目标列表 |
| | | |
| | |
| | | |
| | | protected Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> onHit; |
| | | |
| | | public SkillEffect(SkillBase _skillBase, SkillConfig _skillConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack) |
| | | public SkillEffect(SkillBase _skillBase, SkillConfig _skillConfig, SkillSkinConfig _skillSkinConfig, BattleObject _caster, HB427_tagSCUseSkill _tagUseSkillAttack) |
| | | { |
| | | skillBase = _skillBase; |
| | | skillConfig = _skillConfig; |
| | | skillSkinConfig = _skillSkinConfig; |
| | | caster = _caster; |
| | | tagUseSkillAttack = _tagUseSkillAttack; |
| | | } |
| | |
| | | public virtual void Play(Action<int, List<HB427_tagSCUseSkill.tagSCUseSkillHurt>> _onHit) |
| | | { |
| | | onHit = _onHit; |
| | | if (skillConfig.EffectId > 0) |
| | | if (skillSkinConfig.EffectId > 0) |
| | | { |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.EffectId, caster.GetRectTransform(), caster.Camp, caster.GetModelScale()); |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.EffectId, caster.GetRectTransform(), caster.Camp, caster.GetModelScale()); |
| | | } |
| | | if (skillConfig.EffectId2 > 0) |
| | | if (skillSkinConfig.EffectId2 > 0) |
| | | { |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.EffectId2, caster.GetRectTransform(), caster.Camp, caster.GetModelScale()); |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.EffectId2, caster.GetRectTransform(), caster.Camp, caster.GetModelScale()); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | public virtual void OnMiddleFrameStart(int times) |
| | | { |
| | | if (skillConfig.MStartEffectId <= 0) |
| | | if (skillSkinConfig.MStartEffectId <= 0) |
| | | return; |
| | | // 中摇固定特效 |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillConfig.MStartEffectId, caster.GetTransform(), caster.Camp, caster.GetModelScale()); |
| | | caster.battleField.battleEffectMgr.PlayEffect(caster, skillSkinConfig.MStartEffectId, caster.GetTransform(), caster.Camp, caster.GetModelScale()); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | |
| | | public static class SkillEffectFactory |
| | | { |
| | | public static SkillEffect CreateSkillEffect(SkillBase skillBase, BattleObject caster, SkillConfig skillConfig, HB427_tagSCUseSkill tagUseSkillAttack) |
| | | public static SkillEffect CreateSkillEffect(SkillBase skillBase, BattleObject caster, SkillConfig skillConfig, SkillSkinConfig skillSkinConfig, HB427_tagSCUseSkill tagUseSkillAttack) |
| | | { |
| | | |
| | | switch (skillConfig.effectType) |
| | | switch (skillSkinConfig.effectType) |
| | | { |
| | | case SkillEffectType.Bullet: |
| | | return new BulletSkillEffect(skillBase,skillConfig, caster, tagUseSkillAttack); |
| | | return new BulletSkillEffect(skillBase,skillConfig, skillSkinConfig, caster, tagUseSkillAttack); |
| | | case SkillEffectType.Direct: |
| | | return new NormalSkillEffect(skillBase, skillConfig, caster, tagUseSkillAttack); |
| | | return new NormalSkillEffect(skillBase, skillConfig, skillSkinConfig, caster, tagUseSkillAttack); |
| | | // case SkillEffectType.BuffEffect: |
| | | // return new BuffSkillEffect(skillConfig, caster, targets); |
| | | // case SkillEffectType.StageEffect: |
| | | // return new StageSkillEffect(skillConfig, caster, targets); |
| | | case SkillEffectType.DOTEffect: |
| | | return new DotSkillEffect(skillBase,skillConfig, caster, tagUseSkillAttack); |
| | | return new DotSkillEffect(skillBase,skillConfig, skillSkinConfig, caster, tagUseSkillAttack); |
| | | case SkillEffectType.NoEffect: |
| | | case SkillEffectType.None: |
| | | return new NoEffect(skillBase, skillConfig, caster, tagUseSkillAttack); |
| | | return new NoEffect(skillBase, skillConfig, skillSkinConfig, caster, tagUseSkillAttack); |
| | | default: |
| | | UnityEngine.Debug.LogError("Unknown Skill Effect Type " + skillConfig.effectType + " skill id is " + skillConfig.SkillID); |
| | | return new NoEffect(skillBase, skillConfig, caster, tagUseSkillAttack); |
| | | UnityEngine.Debug.LogError("Unknown Skill Effect Type " + skillSkinConfig.effectType + " skill id is " + skillConfig.SkillID); |
| | | return new NoEffect(skillBase, skillConfig, skillSkinConfig, caster, tagUseSkillAttack); |
| | | break; |
| | | } |
| | | return null; |