using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using UnityEngine; using Debug = UnityEngine.Debug; using UnityEditor.Animations; public class Attack : MonoBehaviour { [Header("子弹预制体")] public GameObject bulletPrefab; [Header("子弹数据")] public BulletData bulletData; [Header("角色对象")] public Role role; //[Header("攻击范围")] public float attackScope; [Header("攻击类型")] public DamageType damageTyp = DamageType.noAttributeDamage; [Header("攻击CD时间")] public float attackCooldown = 1f; // 攻击冷却时间 private float lastAttackTime = 0f; // 上次攻击的时间 [HideInInspector] public List bulltes = new List(); [Header("角色动画控制器")] public Animator animator; //[Header("火焰动画控制器")] public Animator fireAni; [Header("火焰动画控制器")] public List fireAnis; [Header("子弹起始点")] public Transform BulletStartPos; [Header("攻击速度")] public float AttackSpeed=1f; public Vector2 direction; [Header("子弹速度加成")]public float roleBulletSpeedAdd=0f; [Header("子弹数量")] public int BulletNumber = 1; [Header("攻击碰撞体")] public CircleCollider2D attackCollider; [Header("攻击范围图片")] public SpriteRenderer attackRangeSprite; //public float AttackScope //{ // [DebuggerStepThrough] // get => attackScope; // [DebuggerStepThrough] // set // { // attackScope = value; // GetComponent().radius = attackScope; // //Debug.Log("攻击半径"+GetComponent().radius); // } //} public async void Start() { //AttackScope = attackScope; bulletData = new BulletData(); bulletData.BulletScattering = 1; animator.SetFloat("AttackSpeed",AttackSpeed); //CircleCollider2D circleCollider2D = GetComponent(); attackCooldown = transform.parent.GetComponent().AttackCD; SetAttackRange();//设置攻击范围 while (true) { if (attackCollider) { // 检查是否可以进行攻击(基于冷却时间) if (Time.time - lastAttackTime >= attackCooldown) { Collider2D[] colliders = Physics2D.OverlapCircleAll(attackCollider.transform.position, attackCollider.radius); foreach (Collider2D collider in colliders) { Role targetRole = collider.GetComponent(); if (targetRole && targetRole.camp != role.camp) { role.animationHighlight = 1; if (animator!=null) { if (bulletPrefab.GetComponent().myBulletType != BulletType.Spraying) { direction = (targetRole.transform.position - BulletStartPos.position).normalized; } //animator.SetInteger("State", 1); animator.SetTrigger("Attack"); lastAttackTime = Time.time; // 更新上次攻击时间 } else { /*attack(targetRole); lastAttackTime = Time.time; // 更新上次攻击时间*/ } break; // 只攻击一个目标 } else { if (animator != null) { //animator.SetInteger("State", 0); } else { role.animationHighlight = 0; } } } } await Task.Delay(100); // 延迟,避免过于频繁地检测 } else { return; } } } /*public void attack(Role targetRole) { if (bulletPrefab == null) { Debug.LogError("子弹预制体为空"); return; } Vector2 direction = (targetRole.transform.position - transform.position).normalized; if (bulletPrefab.GetComponent().myBulletType == BulletType.Spraying) { GameObject BulletGamobj = GameObject.Instantiate(bulletPrefab, this.transform.root); BulletGamobj.GetComponent().role = role; BulletGamobj.GetComponent().attackObj = this; // BulletGamobj.transform.up = direction; BulletGamobj.transform.position =new Vector2(transform.position.x+0.15f, transform.position.y+0.2f); bulltes.Add(BulletGamobj); return; } else { for (int i = 0; i < bulletData.BulletScattering; i++) { // 改变子弹方向,根据角色自身的攻击范围来计算 GameObject BulletGamobj = GameObject.Instantiate(bulletPrefab, this.transform.root); BulletGamobj.GetComponent().role = role; BulletGamobj.GetComponent().attackObj = this; BulletGamobj.transform.up = direction; BulletGamobj.transform.position = transform.position; bulltes.Add(BulletGamobj); } } }*/ public void Pointattack() { if (bulletPrefab == null) { Debug.LogError("子弹预制体为空"); return; } for (int i = 0; i < BulletNumber; i++) { // 改变子弹方向,根据角色自身的攻击范围来计算 GameObject BulletGamobj = GameObject.Instantiate(bulletPrefab, this.transform.root); BulletGamobj.GetComponent().role = role; BulletGamobj.GetComponent().attackObj = this; BulletGamobj.GetComponent().bulletData.BulletSpeed *= (1 + roleBulletSpeedAdd); BulletGamobj.transform.up = direction; BulletGamobj.transform.position = BulletStartPos.position; bulltes.Add(BulletGamobj); } } public void Fireattack() { if (bulletPrefab == null) { Debug.LogError("子弹预制体为空"); return; } // 检查子弹类型是否为 Spraying if (bulletPrefab.GetComponent().myBulletType == BulletType.Spraying) { // 根据 BulletNumber 生成不同数量和旋转角度的子弹 switch (BulletNumber) { case 1: // 生成一个不旋转的子弹 GenerateBullet(0f, BulletStartPos.position, new Vector2(0, 0)); break; case 3: // 生成三个子弹:一个不旋转,一个向上旋转30度,一个向下旋转30度 GenerateBullet(-30f, BulletStartPos.position, new Vector2(0, -0.2f)); GenerateBullet(0f, BulletStartPos.position, new Vector2(0, 0)); GenerateBullet(30f, BulletStartPos.position, new Vector2(0, 0.2f)); break; default: // 可选:处理其他 BulletNumber 值的情况 Debug.LogWarning($"BulletNumber 为 {BulletNumber} 时未定义的生成逻辑。"); break; } } } private void GenerateBullet(float angle, Vector2 startPos, Vector2 changePos)//角度,旋转中心点 { // 实例化子弹对象并设置父物体为 transform.root GameObject bulletGameObj = GameObject.Instantiate(bulletPrefab, transform.root); // 获取动画组件(如果需要的话) fireAnis.Add(bulletGameObj.GetComponentInChildren()); // 设置子弹的初始位置,保持偏移量 bulletGameObj.transform.position = new Vector2(transform.position.x+1.75f, transform.position.y + 0.2f); bulletGameObj.GetComponent().role = role; bulletGameObj.GetComponent().attackObj = this; // 计算子弹相对于旋转中心的偏移 Vector2 direction = bulletGameObj.transform.position - (Vector3)startPos; // 旋转偏移 direction = Quaternion.Euler(0, 0, angle) * direction; // 更新子弹的位置 bulletGameObj.transform.position = startPos + direction; // 设置子弹的旋转角度 bulletGameObj.transform.rotation = Quaternion.Euler(0, 0, angle); bulletGameObj.transform.position = bulletGameObj.transform.position + (Vector3)changePos; // 将生成的子弹添加到子弹列表中 bulltes.Add(bulletGameObj); } public void EndFire() { foreach (Animator ani in fireAnis) { ani.SetInteger("State", 1); } fireAnis.Clear(); //Debug.Log("停止火焰"); } private void OnDisable() { bulltes.Clear(); } public void SetAttackRange() { // 设置碰撞体的半径 attackCollider.radius = role.AttackRange; // 获取攻击范围图片的原始直径 (SpriteRenderer的bounds.size.x) float spriteDiameter = attackRangeSprite.bounds.size.x; // 计算缩放因子,使得图片的直径与碰撞体的直径匹配 float scaleFactor = role.AttackRange * 2f / spriteDiameter; // * 2f 因为 radius 是半径,图片的尺寸通常是直径 // 设置图片的缩放 attackRangeSprite.transform.localScale = new Vector3(scaleFactor, scaleFactor, 1f); } }