using System.Collections.Generic; using UnityEngine; using System; using DG.Tweening; using Spine; public class SkillBase { protected H0604_tagUseSkillAttack tagUseSkillAttack; protected SkillConfig skillConfig; protected bool isFinished = false; protected BattleField battleField = null; // 战场 protected RectTransform targetNode = null; // 目标节点 protected BattleObject caster = null; // 施法者 protected bool startCounting = false; protected bool pauseState = false; protected int curFrame = 0; protected List triggerFrames = new List(); public SkillBase(BattleObject _caster, SkillConfig _skillCfg, H0604_tagUseSkillAttack vNetData, BattleField _battleField = null) { caster = _caster; skillConfig = _skillCfg; tagUseSkillAttack = vNetData; battleField = _battleField; triggerFrames.Clear(); triggerFrames.AddRange(skillConfig.TriggerFrames); } public virtual void Run() { if (startCounting) { curFrame++; if (triggerFrames.Contains(curFrame)) { OnTriggerEvent(triggerFrames.IndexOf(curFrame), curFrame); } } } protected virtual void OnTriggerEvent(int triggerIndex, int triggerFrame) { } public void Pause() { pauseState = startCounting; startCounting = false; } public void Resume() { startCounting = pauseState; } // 0·移动到距离目标n码,的距离释放(可配置,9999即原地释放,负数则是移动到人物背面,人物要转身) // 1·移动到距离阵容位置n码的距离(如2号位,5号位)释放(即战场中央此类) public virtual void Cast() { // 高亮所有本次技能相关的目标 HighLightAllTargets(); switch (skillConfig.castMode) { case SkillCastMode.StandCast: PlayCastAnimation(() => DoSkillLogic(OnSkillFinished)); break; case SkillCastMode.MoveToTarget: MoveToTarget(_onComplete: () => TurnBack(() => PlayCastAnimation(() => DoSkillLogic(() => { BackToOrigin(OnSkillFinished); })))); break; case SkillCastMode.DashCast: DashToTarget(() => BackToOrigin(OnSkillFinished)); break; default: Debug.LogError("暂时不支持其他的方式释放 有需求请联系策划"); break; } } // 冲刺的技能 动作 跟移动 是同时进行的 移动到目标的一瞬间就要进行技能逻辑 protected void DashToTarget(Action _onComplete) { TrackEntry entry = PlayCastAnimation(); // 做一个微微的提前 MoveToTarget(entry.TrackTime - 0.05f, () => DoSkillLogic(_onComplete)); } protected void GetTargetNode() { targetNode = null; if (skillConfig.castMode == SkillCastMode.StandCast) { // 原地施法 targetNode = caster.heroGo.transform as RectTransform; } else if (skillConfig.castMode == SkillCastMode.MoveToTarget || skillConfig.castMode == SkillCastMode.DashCast) { if (tagUseSkillAttack.AttackID <= 0) { Debug.LogError("技能没有指定目标"); return; } // 移动到目标位置施法 BattleObject _mainTarget = battleField.battleObjMgr.GetBattleObject((int)tagUseSkillAttack.AttackID); if (_mainTarget == null) { Debug.LogError("技能指定的目标不存在"); return; } targetNode = _mainTarget.heroGo.transform as RectTransform; } else if (skillConfig.castMode == SkillCastMode.MoveToFormation) { // TODO YYL targetNode = /*caster.GetEnemyTeamNode();*/ battleField.GetTeamNode(caster.Camp == BattleCamp.Blue ? BattleCamp.Red : BattleCamp.Blue); } else { Debug.LogError("未知的施法方式 技能id:" + skillConfig.SkillID); return; } } protected List GetTargetList() { return battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack); } protected virtual void DoSkillLogic(Action _onComplete = null) { // 子类实现具体的技能逻辑 } protected TrackEntry PlayCastAnimation(Action onComplete = null) { // 播放施法动作 MotionName motionName = skillConfig.GetMotionName(); TrackEntry trackEntry = caster.motionBase.PlayAnimation(motionName, false, onComplete); return trackEntry; } public void MoveToTarget(float duration = 0.2f, Action _onComplete = null) { GetTargetNode(); Vector2 offset = new Vector2(skillConfig.CastDistance, 0); RectTransform selfRect = caster.heroGo.transform as RectTransform; RectTransform targetRect = targetNode; var tweener = BattleUtility.MoveToTarget(selfRect, targetRect, offset, duration, _onComplete); battleField.battleTweenMgr.OnPlayTween(tweener); } public void TurnBack(Action _onComplete) { if (skillConfig.CastDistance < 0) { caster.heroGo.transform.localScale = new Vector3(-1, 1, 1); } _onComplete?.Invoke(); } public void BackToOrigin(Action _onComplete = null) { RectTransform selfRect = caster.heroGo.transform as RectTransform; Vector2 targetAnchoredPos = Vector2.zero; var tween = selfRect.DOAnchorPos(targetAnchoredPos, 0.2f) .SetEase(Ease.Linear) .OnComplete(() => { caster.heroGo.transform.localScale = Vector3.one; _onComplete?.Invoke(); }); battleField.battleTweenMgr.OnPlayTween(tween); } protected void HighLightAllTargets() { // 高亮所有目标 HashSet highlightList = new HashSet(battleField.battleObjMgr.GetBattleObjList(tagUseSkillAttack)); highlightList.Add(caster); // 把这些BO全高亮 或者说把除了这些的都放在遮罩后面 // YYL TODO } public virtual bool IsFinished() { return isFinished; } public virtual void ForceFinished() { isFinished = true; } public void OnSkillFinished() { isFinished = true; } #if UNITY_EDITOR_STOP_USING public virtual List GetTargetList(BattleField _battleField) { SkillTargetType targetType = SkillTargetType.Enemy; SkillTargetRangeType rangeType = SkillTargetRangeType.LowestHP; List affectList = _battleField.battleObjMgr.GetTargetList(caster, targetType, rangeType); return affectList; } public virtual List>> GetDamageList(BattleField _battleField) { Debug.LogError("SkillBase GetDamageList should be overridden by derived class"); return null; } #endif }