public override void Execute() { if (skillInfo == null || timelineList == null) { return; } if (!character) { return; } if (character.status == Status.Dead) { return; } foreach (var kvp in character.characterInfo.passiveIdDic) { LuaInterface.LuaFunction func = PassiveSkillController.instance.GetPassiveSkillLuaFunction(PassiveSkillController.PLAY_SKILL, kvp.Key); if (func != null) { func.Call(character, kvp.Value); } } int layer = (int)LayerType.Fight; if (FightController.instance.fightStatus == FightStatus.Normal) { if (skillInfo.skillData.pauseTime > 0) { TimeScaler.instance.PauseTrigger(character, skillInfo.skillData.pauseTime / Game.GameSetting.instance.speed, GameScaleMode.Animator, Game.GameSetting.instance.speed, character.anim); } } if (skillInfo.skillData.showTime) { Logic.UI.SkillBanner.View.SkillBannerView skillBannerView = Logic.UI.SkillBanner.View.SkillBannerView.Open(); skillBannerView.Show(skillInfo); if (isPlayer && FightController.instance.fightType != FightType.SkillDisplay) { Logic.UI.SkillHead.View.SkillHeadView.SetRoleInfo(character.characterInfo.roleInfo, SkillHeadViewShowType.Left); } } MechanicsData mechanicsData = null; #region camera close up if (GameSetting.instance.closeupCameraable) { if (FightController.instance.fightStatus == FightStatus.Normal) { if ((isPlayer || (!isPlayer && EnemyController.instance.isBoss(character.characterInfo.instanceID))) && skillInfo.animationData.closeup) //if (isPlayer && skillInfo.animationData.closeup) { FightController.instance.isCloseup = true; layer = (int)LayerType.Closeup; EnemyController.instance.ShowHPBarViews(false); PlayerController.instance.ShowHPBarViews(false); if (Skill.SkillUtil.GetSkillMechanicsType(skillInfo) == MechanicsType.None) { Logic.UI.SkillBar.Controller.SkillBarController.instance.Show(false); } Judge.Controller.JudgeController.instance.ShowDamageBarViewPool(false); Cameras.Controller.CameraController.instance.ShowMainCamera(false); Transform parent = TransformUtil.Find(Logic.Cameras.Controller.CameraController.CAMERA_NODE, character.transform, true); Cameras.Controller.CameraController.instance.ShowCloseupCamera(character, parent); TransformUtil.SwitchLayer(character.transform, layer); List <CharacterEntity> targets = CharacterUtil.SwitchCharacterLayer(skillInfo, timelineList, isPlayer, layer); FightController.instance.SetCloseupCharacter(character, targets); } } } #endregion #region camera /* #if UNITY_EDITOR * if (FightController.imitate || character.characterInfo.roleInfo.heroData.starMax >= 5) * { #else * if (character.characterInfo.roleInfo.heroData.starMax >= 5) * { #endif * if (skillInfo.skillData.skillType == SkillType.Skill) * { * switch (skillInfo.animationData.animType) * { * case AnimType.Root: * { * float backTime = skillInfo.skillData.timeline.First().Key - 0.3f; * if (backTime > 0.5f) * { * float delay = 0.3f; * CameraController.instance.CloseTarget(character, delay); * //int layerNone = (int)LayerType.None; * //SwitchCharactersLayer(layerNone, false); * //CameraController.instance.ResetMainCamera(backTime, () => * //{ * // SwitchCharactersLayer((int)LayerType.Fight, true); * //}); * CameraController.instance.ResetMainCamera(backTime, null); * } * } * break; * case AnimType.Trace: * { * float backTime = skillInfo.animationData.moveTime; * if (backTime > 0.5f) * { * float delay = 0.3f; * CameraController.instance.CloseTarget(character, delay); * //int layerNone = (int)LayerType.None; * //SwitchCharactersLayer(layerNone, false); * //CameraController.instance.ResetMainCamera(backTime, () => * //{ * // SwitchCharactersLayer((int)LayerType.Fight, true); * //}); * CameraController.instance.ResetMainCamera(backTime, null); * } * } * break; * case AnimType.Run: * break; * * } * } #if UNITY_EDITOR * } #else * } #endif * */ if (FightController.instance.fightStatus == FightStatus.Normal && skillInfo.skillData.cameraLength > 0) { CameraController.instance.CloseTarget(character, skillInfo.skillData.cameraTime); CameraController.instance.ResetMainCamera(skillInfo.skillData.cameraTime + skillInfo.skillData.cameraLength); } #endregion if (skillInfo.animationData.animType != AnimType.Run) { AnimatorUtil.Play(character.anim, Animator.StringToHash(AnimatorUtil.BASE_LAYER + skillInfo.animationData.animName), 0, 0f); } switch (skillInfo.animationData.animType) { case AnimType.Root: case AnimType.Trace: PlayCasterEffect(layer); break; } #region 远程技能特效 if (skillInfo.animationData.animType == AnimType.Root) { #region aoe //aoe 与 单体互斥 if (skillInfo.skillData.aoeFlyEffects.Length > 0) { #region aeo fly 只有表现,没有效果 List <float> timelineKeys = skillInfo.skillData.timeline.GetKeys(); for (int j = 0, count = timelineList.Count; j < count; j++) { Dictionary <uint, List <KeyValuePair <uint, uint> > > mechanicsDic = timelineList[j]; List <uint> mechanicsKeys = mechanicsDic.GetKeys(); uint effectId = 0; if (skillInfo.skillData.aoeFlyEffects.Length > j) { effectId = skillInfo.skillData.aoeFlyEffects[j]; } for (int k = 0, kCount = mechanicsKeys.Count; k < kCount; k++) { uint mechanicsId = mechanicsKeys[k]; mechanicsData = MechanicsData.GetMechanicsDataById(mechanicsId); List <KeyValuePair <uint, uint> > tids; if (mechanicsData.mechanicsType == MechanicsType.Reborn) { tids = CharacterUtil.FindDeadTargets(mechanicsData.rangeType, mechanicsData.targetType, isPlayer); if (mechanicsData.rangeType == RangeType.All || mechanicsData.rangeType == RangeType.AllAbsolutely) { tids.AddRange(CharacterUtil.FindAllTargets(mechanicsData.targetType, isPlayer)); } } else { if (mechanicsData.rangeType == RangeType.All || mechanicsData.rangeType == RangeType.AllAbsolutely) { tids = CharacterUtil.FindAllTargets(mechanicsData.targetType, isPlayer); } else { tids = mechanicsDic[mechanicsId]; } } float delay = 0f; if (GameSetting.instance.effectable) { EffectInfo effectInfo = new EffectInfo(effectId); if (effectInfo.effectData != null) { effectInfo.character = character; effectInfo.target = character; effectInfo.skillInfo = skillInfo; effectInfo.delay = timelineKeys[j] + effectInfo.effectData.delay; switch (effectInfo.effectData.effectType) { case EffectType.Trace: case EffectType.CurveTrace: //感觉跟直线轨迹是一样的 uint positionId = GetTargetAreaPositionId(mechanicsData, tids, isPlayer); PositionData positionData = PositionData.GetPostionDataById(positionId); effectInfo.rotateAngles = skillInfo.rotateAngles; //FightController.instance.Rotate(character.transform, positionData.position); Vector3 offset = effectInfo.effectData.offset; if (!isPlayer) { offset.x *= -1; } effectInfo.pos = PositionData.GetPostionDataById(character.positionId).position + offset; float positionRow = PositionData.GetEnemyPositionLevels(character.positionId, positionId); effectInfo.time = effectInfo.effectData.moveTime * (positionRow * GameConfig.timePercent + 1f); Vector3 endOffset = effectInfo.effectData.endOffset; if (!isPlayer) { endOffset.x *= -1; } effectInfo.endPos = positionData.position + endOffset; delay = effectInfo.effectData.delay + effectInfo.time; EffectController.instance.PlayEffect(effectInfo, layer); break; } } } PlayAOEEffects(delay, layer);//aoe飞行特效只计算特效延迟和飞行时间,不加时间点,aoe特效会计入时间点 } } } else if (skillInfo.skillData.aoeEffects.Length > 0) { #endregion PlayAOEEffects(0f, layer); } #endregion #region fly effects else { bool isLastTarget = false; List <float> timelineKeys = skillInfo.skillData.timeline.GetKeys(); Dictionary <CharacterEntity, int> judgeTypeDic = new Dictionary <CharacterEntity, int>(); for (int j = 0, count = timelineList.Count; j < count; j++) { Dictionary <uint, List <KeyValuePair <uint, uint> > > mechanicsDic = timelineList[j]; List <uint> mechanicsKeys = mechanicsDic.GetKeys(); List <Triple <float, float, float> > mechanicsValues = skillInfo.skillData.mechanicsValues[j]; for (int k = 0, kCount = mechanicsKeys.Count; k < kCount; k++) { uint mechanicsId = mechanicsKeys[k]; mechanicsData = MechanicsData.GetMechanicsDataById(mechanicsId); List <KeyValuePair <uint, uint> > tids; if (mechanicsData.mechanicsType == MechanicsType.Reborn)//获取重生目标 { tids = CharacterUtil.FindDeadTargets(mechanicsData.rangeType, mechanicsData.targetType, isPlayer); if (mechanicsData.rangeType == RangeType.All || mechanicsData.rangeType == RangeType.AllAbsolutely) { tids.AddRange(CharacterUtil.FindAllTargets(mechanicsData.targetType, isPlayer)); } } else { if (mechanicsData.rangeType == RangeType.All || mechanicsData.rangeType == RangeType.AllAbsolutely) { tids = CharacterUtil.FindAllTargets(mechanicsData.targetType, isPlayer); } else { tids = mechanicsDic[mechanicsId]; } } Triple <float, float, float> mechanicsValue = mechanicsValues[k]; uint effectId = 0; if (skillInfo.skillData.flyEffectIds.Count > j) { effectId = skillInfo.skillData.flyEffectIds[j];//所有目标都发射伤害特效 } for (int m = 0, mCount = tids.Count; m < mCount; m++) { KeyValuePair <uint, uint> tid = tids[m]; if (m == mCount - 1 && k == kCount - 1 && j == count - 1)//最后一个移动特效 { isLastTarget = true; } else { isLastTarget = false; } CharacterEntity target1 = CharacterUtil.FindTarget(mechanicsData.mechanicsType, mechanicsData.targetType, isPlayer, tid.Key); CharacterEntity target2 = CharacterUtil.FindTarget(mechanicsData.mechanicsType, mechanicsData.targetType, isPlayer, tid.Value); if (target1 == null) { continue; } float delay = timelineKeys[j]; if (GameSetting.instance.effectable) { EffectInfo effectInfo = new EffectInfo(effectId); if (effectInfo.effectData != null) { effectInfo.character = character; effectInfo.skillInfo = skillInfo; effectInfo.delay = delay + effectInfo.effectData.delay; effectInfo.isLastTarget = isLastTarget; effectInfo.target = target1; effectInfo.mechanicsData = mechanicsData; effectInfo.mechanicsValue = mechanicsValue; switch (effectInfo.effectData.effectType) { case EffectType.Root: //{ //if (isPlayer != target1.isPlayer)//当目标为友方是不旋转 //{ // PositionData positionData = PositionData.GetPostionDataById(target1.positionId); // FightController.instance.Rotate(character.transform, positionData.position); //} effectInfo.rotateAngles = skillInfo.rotateAngles; //} break; case EffectType.LockTarget: //锁定目标技能特效 //{ // if (isPlayer != target1.isPlayer) // { // PositionData positionData = PositionData.GetPostionDataById(target1.positionId); // FightController.instance.Rotate(character.transform, positionData.position); // } //} effectInfo.rotateAngles = skillInfo.rotateAngles; break; case EffectType.Trace: case EffectType.CurveTrace: //感觉跟直线轨迹是一样的 { PositionData positionData = PositionData.GetPostionDataById(target1.positionId); //effectInfo.rotateAngles = FightController.instance.Rotate(character.transform, positionData.position); effectInfo.rotateAngles = skillInfo.rotateAngles; Vector3 offset = effectInfo.effectData.offset; if (!isPlayer) { offset.x *= -1; } effectInfo.pos = PositionData.GetPostionDataById(character.positionId).position + offset; float positionRow = PositionData.GetEnemyPositionLevels(character.positionId, target1.positionId); effectInfo.time = effectInfo.effectData.moveTime * (positionRow * GameConfig.timePercent + 1f); Vector3 endOffset = effectInfo.effectData.endOffset; if (!isPlayer) { endOffset.x *= -1; } effectInfo.endPos = positionData.position + endOffset + new Vector3(0, target1.height * 0.6f, 0); } break; } delay += effectInfo.effectData.delay + effectInfo.time; EffectController.instance.PlayEffect(effectInfo, layer); } } if (FightController.instance.fightStatus == FightStatus.Normal)//矫正因暂停导致时间线推迟 { delay -= skillInfo.skillData.pauseTime; } int judgeType = 0; if (!judgeTypeDic.ContainsKey(target1)) { judgeType = JudgeUtil.GetJudgeResult(character, target1, target2, (int)skillInfo.skillData.skillId); judgeTypeDic[target1] = judgeType; if (judgeType == 0) { EffectController.instance.RemoveEffectByPrefabName(EffectController.SPEED_LINE); } } else { judgeType = judgeTypeDic[target1]; } if (isPlayer) { MechanicsController.instance.PlayerMechanics(skillInfo, mechanicsData, character, target1, target2, mechanicsValue, delay, judgeType, isLastTarget); } else { MechanicsController.instance.EnemyMechanics(skillInfo, mechanicsData, character, target1, target2, mechanicsValue, delay, judgeType, isLastTarget); } } } } judgeTypeDic.Clear(); judgeTypeDic = null; } #endregion } for (int i = 0, count = skillInfo.skillData.audioIds.Count; i < count; i++) { AudioData audioData = AudioData.GetAudioDataById(skillInfo.skillData.audioIds[i]); if (audioData != null) { AudioController.instance.PlayAudio(audioData.audioName, !audioData.accelerate, skillInfo.skillData.audioDelay); } } Hero.Model.HeroData heroData = Hero.Model.HeroData.GetHeroDataByID((int)character.characterInfo.baseId); AudioData attackAudioData = AudioData.GetAudioDataById(heroData.audioAttack); if (attackAudioData != null) { AudioController.instance.PlayAudio(attackAudioData.audioName, !attackAudioData.accelerate); } #endregion finish = true; }
public override void Execute() { if (!character || mechanicsData == null || skillInfo == null) { return; } int layer = (int)LayerType.Fight; int stateNameHash = 0; AnimatorPlayType animatorPlayType = AnimatorPlayType.None; if (mechanicsType == MechanicsType.None) { mechanicsType = mechanicsData.mechanicsType; } switch (mechanicsType) { //攻击 case MechanicsType.Damage: case MechanicsType.DrainDamage: case MechanicsType.IgnoreDefenseDamage: case MechanicsType.ImmediatePercentDamage: case MechanicsType.SwimmyExtraDamage: case MechanicsType.LandificationExtraDamage: case MechanicsType.BleedExtraDamage: case MechanicsType.FrozenExtraDamage: case MechanicsType.PoisoningExtraDamage: case MechanicsType.TagExtraDamage: case MechanicsType.IgniteExtraDamage: if ((character.status == Status.BootSkill && breakable) || character.status != Status.BootSkill) //非引导技能,或者引导技能可打断 { animatorPlayType = AnimatorPlayType.Play; switch (FightController.instance.fightType) { case FightType.PVE: case FightType.Arena: case FightType.DailyPVE: case FightType.Expedition: case FightType.WorldTree: case FightType.WorldBoss: case FightType.FirstFight: case FightType.SkillDisplay: case FightType.MineFight: #if UNITY_EDITOR case FightType.Imitate: #endif if (Logic.Game.GameSetting.instance.closeupCameraable) { if (FightController.instance.fightStatus == FightStatus.Normal) { if (skillInfo.animationData.closeup) { if (mechanicsMaker.isPlayer || (!mechanicsMaker.isPlayer && Logic.Character.Controller.EnemyController.instance.isBoss(mechanicsMaker.characterInfo.instanceID))) //只有玩家和boss有特写镜头 { layer = (int)LayerType.Closeup; } } } } break; case FightType.PVP: case FightType.FriendFight: case FightType.ConsortiaFight: break; } switch (skillInfo.skillData.skillType) { case SkillType.Hit: if (Fight.Controller.FightController.instance.fightStatus == FightStatus.Normal) { stateNameHash = AnimatorUtil.GETHIT_1_ID; } break; case SkillType.Skill: case SkillType.Aeon: switch (Fight.Controller.FightController.instance.fightStatus) { case FightStatus.FloatComboing: character.anim.speed = Game.GameSetting.instance.speed; stateNameHash = AnimatorUtil.FLOATGETHIT_ID; Cameras.Controller.CameraController.instance.Shake(); break; case FightStatus.TumbleComboing: character.anim.speed = Game.GameSetting.instance.speed; stateNameHash = AnimatorUtil.TUMBLEGETHIT_ID; Cameras.Controller.CameraController.instance.Shake(); break; case FightStatus.Normal: stateNameHash = AnimatorUtil.GETHIT_2_ID; break; } break; } character.SetStatus(Status.GetHit); } break; case MechanicsType.Float: animatorPlayType = AnimatorPlayType.Play; if (AnimatorUtil.GetBool(character.anim, AnimatorUtil.FLOATING) || AnimatorUtil.GetBool(character.anim, AnimatorUtil.TUMBLE)) //忽略再次连击 { switch (Fight.Controller.FightController.instance.fightStatus) { case FightStatus.FloatComboing: character.anim.speed = Game.GameSetting.instance.speed; stateNameHash = AnimatorUtil.FLOATGETHIT_ID; Cameras.Controller.CameraController.instance.Shake(); break; case FightStatus.TumbleComboing: character.anim.speed = Game.GameSetting.instance.speed; stateNameHash = AnimatorUtil.TUMBLEGETHIT_ID; Cameras.Controller.CameraController.instance.Shake(); break; case FightStatus.Normal: stateNameHash = AnimatorUtil.GETHIT_2_ID; break; } } else { if (character.floatable) { if (skillInfo.skillData.skillType == SkillType.Aeon) { stateNameHash = AnimatorUtil.FLOATGETHIT_ID; } else { stateNameHash = AnimatorUtil.FLOATSTART_ID; if (mechanicsMaker.isPlayer) { if (PlayerController.instance.HasFloatHeros()) { layer = (int)LayerType.FightCombo; Fight.Controller.FightController.instance.SetComboCharacter(mechanicsMaker, character); AnimatorUtil.SetBool(character.anim, AnimatorUtil.FLOATING, true); Fight.Controller.FightController.instance.fightStatus = FightStatus.FloatWaiting; } } else { if (EnemyController.instance.HasFloatEnemies()) { layer = (int)LayerType.FightCombo; Fight.Controller.FightController.instance.SetComboCharacter(mechanicsMaker, character); AnimatorUtil.SetBool(character.anim, AnimatorUtil.FLOATING, true); Fight.Controller.FightController.instance.fightStatus = FightStatus.FloatWaiting; } } } } else { stateNameHash = AnimatorUtil.GETHIT_2_ID; } } character.SetStatus(Status.GetHit); break; case MechanicsType.Tumble: animatorPlayType = AnimatorPlayType.Play; if (AnimatorUtil.GetBool(character.anim, AnimatorUtil.TUMBLE) || AnimatorUtil.GetBool(character.anim, AnimatorUtil.FLOATING)) //忽略再次连击 { switch (Fight.Controller.FightController.instance.fightStatus) { case FightStatus.FloatComboing: character.anim.speed = Game.GameSetting.instance.speed; stateNameHash = AnimatorUtil.FLOATGETHIT_ID; Cameras.Controller.CameraController.instance.Shake(); break; case FightStatus.TumbleComboing: character.anim.speed = Game.GameSetting.instance.speed; stateNameHash = AnimatorUtil.TUMBLEGETHIT_ID; Cameras.Controller.CameraController.instance.Shake(); break; case FightStatus.Normal: stateNameHash = AnimatorUtil.GETHIT_2_ID; break; } } else { if (character.floatable) { if (skillInfo.skillData.skillType == SkillType.Aeon) { stateNameHash = AnimatorUtil.TUMBLEGETHIT_ID; } else { stateNameHash = AnimatorUtil.TUMBLESTART_ID; if (mechanicsMaker.isPlayer) { if (PlayerController.instance.HasTumbleHeros()) { layer = (int)LayerType.FightCombo; Fight.Controller.FightController.instance.SetComboCharacter(mechanicsMaker, character); AnimatorUtil.SetBool(character.anim, AnimatorUtil.TUMBLE, true); Fight.Controller.FightController.instance.fightStatus = FightStatus.TumbleWaiting; } } else { if (EnemyController.instance.HasTumbleEnemies()) { layer = (int)LayerType.FightCombo; Fight.Controller.FightController.instance.SetComboCharacter(mechanicsMaker, character); AnimatorUtil.SetBool(character.anim, AnimatorUtil.TUMBLE, true); Fight.Controller.FightController.instance.fightStatus = FightStatus.TumbleWaiting; } } } } else { stateNameHash = AnimatorUtil.GETHIT_2_ID; } } character.SetStatus(Status.GetHit); break; } if (stateNameHash != 0) { switch (animatorPlayType) { case AnimatorPlayType.Play: //if (Fight.Controller.FightController.instance.fightStatus == FightStatus.Normal) //{ if (character.canPlayAnimator && character.isInPlace) { AnimatorUtil.Play(character.anim, stateNameHash, 0, 0f); } //} //else // AnimatorUtil.Play(character.anim, Animator.StringToHash(AnimatorUtil.BASE_LAYER + animName), 0, 0f); break; case AnimatorPlayType.Trigger: //if (character.canPlayAnimator && character.isInPlace) // AnimatorUtil.SetTrigger(character.anim, stateNameHash); break; } } if (mechanicsData.audioType != 0) { List <AudioData> audios = AudioData.GetAuidoDatasByType(mechanicsData.audioType); if (audios.Count > 0) { int index = Random.Range(0, audios.Count); AudioData audioData = audios[index]; AudioController.instance.PlayAudio(audioData.audioName, !audioData.accelerate, mechanicsData.audioDelay); } } Hero.Model.HeroData heroData = Hero.Model.HeroData.GetHeroDataByID((int)character.characterInfo.baseId); AudioData attackAudioData = AudioData.GetAudioDataById(heroData.audioUnderAttack); if (attackAudioData != null) { AudioController.instance.PlayAudio(attackAudioData.audioName, !attackAudioData.accelerate); } if (Logic.Game.GameSetting.instance.effectable) { PlayEffect(layer); } finish = true; }