using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine; using System.Collections; using DragonLi.Frame; using UnityEngine.AI; using Valheim; public abstract class SkillLogicBase : ScriptableObject { [Header("技能基础数据")] public SkillData skillData; public int skillCount=1;//技能次数 /// /// 判断是否可以使用技能,例如冷却、蓝量、距离等 /// 这里仅做示例,可根据项目需求扩展 /// public virtual bool CanUseSkill(GameObject caster) { // 简单示例:若没有目标就不能释放 //if (target == null) return false; //if (caster.GetComponent() != null && !caster.GetComponent().isUserSkill) return false; // 其他逻辑检查,如距离、能量值、CD时间等 return true; } /// /// 技能执行的核心方法,通常使用协程 /// public abstract IEnumerator ExecuteSkill(GameObject caster, GameObject target); /// /// 获取技能伤害区间 /// public virtual float CalculateDamage() { // 简单随机 return Random.Range(skillData.MinAtk/skillCount, (skillData.MaxAtk + 1)/skillCount); } } /// /// 单体伤害技能 /// [CreateAssetMenu(fileName = "SingleAttackSkill", menuName = "Skills/SingleAttackSkill")] public class SingleAttackSkill : SkillLogicBase { public override IEnumerator ExecuteSkill(GameObject caster, GameObject target) { skillCount = 1; if (skillData.SkillId == 1) { skillCount = 2; } var agent = caster.GetComponent(); // 1. 前摇等待 yield return new WaitForSeconds(skillData.UserTime); GameManager.Ins.CreateSkill(skillData.SkillId,agent.skillPos.position,skillData.SkillTime,target.transform); for (int i = 0; i < skillCount; i++) { // 2. 进行伤害计算 float damage = CalculateDamage(); // 根据需求,对目标进行伤害处理 // Debug.LogError($"技能[{skillData.SkillName}] 对目标造成了 {damage} 点伤害! 描述:{skillData.SkillDesc}"); // 如果技能有持续时长,可以继续等待 // if (skillData.SkillTime > 0) // { // yield return new WaitForSeconds(skillData.SkillTime); // // 如果是持续伤害,可能需要多次结算 // // 这里只是演示一次结算 // } if (target != null) { IDamagable damagable = target.GetComponent(); if (damagable != null) { damagable.ApplyDamage(damage, false, caster.transform); } } else { // 5. 如果目标为 null,则进行自身范围检测 // 配置检测半径,可根据需求修改或放入配置数据中 float detectionRadius = 5f; Collider[] hitColliders = Physics.OverlapSphere(caster.transform.position, detectionRadius); foreach (var col in hitColliders) { // 只对标签为 "enemy" 的对象进行伤害处理 if (col.CompareTag("Enemy")) { IDamagable damagable = col.GetComponent(); if (damagable != null) { damagable.ApplyDamage(damage, false, caster.transform); } } } } yield return new WaitForSeconds(0.2f); } Debug.Log("取消技能"); yield return new WaitForSeconds(skillData.SkillTime); caster.GetComponent().AnimatorComponent.SetBool("userSkill", false); // 技能执行结束 yield break; } } /// /// 范围伤害技能 /// [CreateAssetMenu(fileName = "RangeAttackSkill", menuName = "Skills/RangeAttackSkill")] public class RangeAttackSkill : SkillLogicBase { [Header("范围攻击配置")] public float attackRadius = 30f; // 攻击半径 public LayerMask targetLayer; // 目标所属的图层 public override IEnumerator ExecuteSkill(GameObject caster, GameObject target) { skillCount = 1; var agent = caster.GetComponent(); // 1. 前摇等待 yield return new WaitForSeconds(skillData.UserTime); GameManager.Ins.CreateSkill(skillData.SkillId,agent.skillPos.position,skillData.SkillTime,target.transform); for (int i = 0; i < skillData.SkillTime; i++) { targetLayer=target.layer; // 2. 查找范围内所有可攻击的目标 // 这里以 Physics.OverlapSphere 为例,需要目标带有 Collider Collider[] hitColliders = Physics.OverlapSphere(caster.transform.position, attackRadius, targetLayer); // 3. 对每个目标造成伤害 foreach (var col in hitColliders) { // 简单示例:计算伤害 float damage = CalculateDamage(); //Debug.LogError($"[范围攻击] 技能[{skillData.SkillName}] 对 [{col.name}] 造成 {damage} 点伤害!"); // 在这里可以调用目标的受伤方法(如 target.TakeDamage(damage)) IDamagable damagable = col.GetComponent(); if (damagable != null) { damagable.ApplyDamage(damage, false, caster.transform); } } yield return new WaitForSeconds(1f); } // 4. 如果技能有持续时间,可在这段时间内多次范围伤害 // 这里演示一次,如果需要多段伤害,可用循环或协程多次执行 // if (skillData.SkillTime > 0) // { // // 示例:间隔 0.5 秒,再次范围伤害一次 // yield return new WaitForSeconds(skillData.SkillTime); // // 也可以再次执行范围伤害或结束 // // ... // } Debug.Log("取消技能"); yield return new WaitForSeconds(skillData.SkillTime); caster.GetComponent().AnimatorComponent.SetBool("userSkill", false); // 技能执行结束 yield break; } } //持续伤害技能 [CreateAssetMenu(fileName = "DotAttackSkill", menuName = "Skills/DotAttackSkill")] public class DotAttackSkill : SkillLogicBase { [Header("持续伤害配置")] public float tickInterval = 1f; // 每隔多少秒造成一次伤害 public int tickCount = 3; // 一共造成几次伤害 public override IEnumerator ExecuteSkill(GameObject caster, GameObject target) { // 1. 前摇等待 yield return new WaitForSeconds(skillData.UserTime); var agent = caster.GetComponent(); GameManager.Ins.CreateSkill(skillData.SkillId,agent.skillPos.position,10,target.transform); // 2. 开始持续伤害 int currentTick = 0; while (currentTick < tickCount) { // 计算伤害 float damage = CalculateDamage(); Debug.Log($"[持续伤害] 技能[{skillData.SkillName}] 第{currentTick + 1}次,对 [{target.name}] 造成 {damage} 点伤害!"); // 在这里可以调用目标的受伤方法(如 target.TakeDamage(damage)) currentTick++; // 如果到了 tickCount 次或超过技能持续时间,则退出 if (currentTick >= tickCount || (skillData.SkillTime > 0 && currentTick * tickInterval >= skillData.SkillTime)) { break; } // 等待下一次伤害 yield return new WaitForSeconds(tickInterval); } yield break; } } /// /// Buff技能 /// [CreateAssetMenu(fileName = "BuffSkill", menuName = "Skills/BuffSkill")] public class BuffSkill : SkillLogicBase { [Header("Buff配置")] public float buffValue = 1.2f; // 假设加成倍数,比如攻击力提升 20% public bool isAttackBuff = true; // 简单示例:是否是攻击力Buff public override IEnumerator ExecuteSkill(GameObject caster, GameObject target) { var agent = caster.GetComponent(); GameManager.Ins.CreateSkill(skillData.SkillId,agent.skillPos.position,10,target.transform); // 1. 前摇等待 yield return new WaitForSeconds(skillData.UserTime); if (target != null) { Debug.Log($"[Buff] 技能[{skillData.SkillName}] 给 [{target.name}] 施加 Buff,持续 {skillData.SkillTime} 秒"); } // 2. 给目标施加 Buff // 在这里实现具体的 Buff 效果,例如: // 1) 提升攻击力 // 2) 提升防御力 // 3) 提升移动速度 // 4) 免控、减伤等等 // 例如:如果目标有一个 PetStatus/CharacterStatus 脚本来管理属性 // var status = target.GetComponent(); // if (status != null && isAttackBuff) // { // status.attack *= buffValue; // } // 3. 持续时间内维持 Buff 效果 if (skillData.SkillTime > 0) { yield return new WaitForSeconds(skillData.SkillTime); // Buff 结束时,恢复属性 // if (status != null && isAttackBuff) // { // status.attack /= buffValue; // } if (skillData.SkillId == 3) { int index= Random.Range(1,GameManager.Ins.PetList.Count); GameManager.Ins.PetList[index].AddBlood(0,GameManager.Ins.PetList[index].OriginHealth*0.25f); } Debug.Log($"[Buff] 技能[{skillData.SkillName}] Buff 效果结束"); } agent.AnimatorComponent.SetBool("userSkill", false); yield break; } public void AddHpSkill() { } }