UnityCommon/Role/Attack.cs

291 lines
10 KiB
C#
Raw Normal View History

2024-12-05 16:25:46 +08:00
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
2024-12-14 23:20:36 +08:00
using System.Linq;
2024-12-05 16:25:46 +08:00
using System.Threading.Tasks;
using UnityEngine;
using Debug = UnityEngine.Debug;
2024-12-23 14:28:04 +08:00
using UnityEditor.Animations;
2024-12-05 16:25:46 +08:00
public class Attack : MonoBehaviour
{
2024-12-12 23:03:57 +08:00
[Header("子弹预制体")] public GameObject bulletPrefab;
[Header("子弹数据")] public BulletData bulletData;
[Header("角色对象")] public Role role;
2024-12-26 18:11:09 +08:00
//[Header("攻击范围")] public float attackScope;
2024-12-12 23:03:57 +08:00
[Header("攻击类型")] public DamageType damageTyp = DamageType.noAttributeDamage;
2024-12-18 14:16:52 +08:00
[Header("攻击CD时间")] public float attackCooldown = 1f; // 攻击冷却时间
2024-12-12 23:03:57 +08:00
private float lastAttackTime = 0f; // 上次攻击的时间
[HideInInspector]
public List<GameObject> bulltes = new List<GameObject>();
2024-12-17 17:15:32 +08:00
[Header("角色动画控制器")] public Animator animator;
2024-12-26 11:19:45 +08:00
//[Header("火焰动画控制器")] public Animator fireAni;
[Header("火焰动画控制器")] public List<Animator> fireAnis;
2024-12-17 18:07:43 +08:00
[Header("子弹起始点")] public Transform BulletStartPos;
2024-12-23 14:28:04 +08:00
[Header("攻击速度")] public float AttackSpeed=1f;
2024-12-17 18:07:43 +08:00
public Vector2 direction;
2024-12-25 23:08:05 +08:00
[Header("子弹速度加成")]public float roleBulletSpeedAdd=0f;
[Header("子弹数量")] public int BulletNumber = 1;
2024-12-26 18:11:09 +08:00
[Header("攻击碰撞体")] public CircleCollider2D attackCollider;
[Header("攻击范围图片")] public SpriteRenderer attackRangeSprite;
//public float AttackScope
//{
// [DebuggerStepThrough]
// get => attackScope;
// [DebuggerStepThrough]
// set
// {
// attackScope = value;
// GetComponent<CircleCollider2D>().radius = attackScope;
// //Debug.Log("攻击半径"+GetComponent<CircleCollider2D>().radius);
// }
//}
2024-12-12 23:03:57 +08:00
2024-12-05 16:25:46 +08:00
public async void Start()
{
2024-12-26 18:11:09 +08:00
//AttackScope = attackScope;
2024-12-05 16:25:46 +08:00
bulletData = new BulletData();
bulletData.BulletScattering = 1;
2024-12-23 14:28:04 +08:00
animator.SetFloat("AttackSpeed",AttackSpeed);
2024-12-26 18:11:09 +08:00
//CircleCollider2D circleCollider2D = GetComponent<CircleCollider2D>();
2024-12-11 16:51:55 +08:00
2024-12-23 16:57:40 +08:00
attackCooldown = transform.parent.GetComponent<enemy>().AttackCD;
2024-12-23 14:28:04 +08:00
2024-12-26 18:11:09 +08:00
SetAttackRange();//设置攻击范围
2024-12-23 14:28:04 +08:00
2024-12-12 23:03:57 +08:00
while (true)
{
2024-12-26 18:11:09 +08:00
if (attackCollider)
{
2024-12-12 23:03:57 +08:00
// 检查是否可以进行攻击(基于冷却时间)
if (Time.time - lastAttackTime >= attackCooldown)
2024-12-05 16:25:46 +08:00
{
2024-12-26 18:11:09 +08:00
Collider2D[] colliders = Physics2D.OverlapCircleAll(attackCollider.transform.position, attackCollider.radius);
2024-12-12 23:03:57 +08:00
foreach (Collider2D collider in colliders)
2024-12-05 16:25:46 +08:00
{
2024-12-12 23:03:57 +08:00
Role targetRole = collider.GetComponent<Role>();
if (targetRole && targetRole.camp != role.camp)
{
2024-12-14 23:20:36 +08:00
role.animationHighlight = 1;
2024-12-17 17:15:32 +08:00
if (animator!=null)
{
2024-12-17 18:07:43 +08:00
if (bulletPrefab.GetComponent<Bullet>().myBulletType != BulletType.Spraying)
{
2024-12-18 14:16:52 +08:00
direction = (targetRole.transform.position - BulletStartPos.position).normalized;
2024-12-17 18:07:43 +08:00
}
2024-12-18 16:55:00 +08:00
//animator.SetInteger("State", 1);
animator.SetTrigger("Attack");
2024-12-17 17:15:32 +08:00
lastAttackTime = Time.time; // 更新上次攻击时间
2024-12-17 18:07:43 +08:00
2024-12-17 17:15:32 +08:00
}
else
{
2024-12-25 23:08:05 +08:00
/*attack(targetRole);
lastAttackTime = Time.time; // 更新上次攻击时间*/
2024-12-17 17:15:32 +08:00
}
2024-12-12 23:03:57 +08:00
break; // 只攻击一个目标
}
2024-12-14 23:20:36 +08:00
else
{
2024-12-17 17:15:32 +08:00
if (animator != null)
{
2024-12-18 16:55:00 +08:00
//animator.SetInteger("State", 0);
2024-12-17 17:15:32 +08:00
}
else
{
role.animationHighlight = 0;
}
2024-12-14 23:20:36 +08:00
}
2024-12-05 16:25:46 +08:00
}
2024-12-14 23:20:36 +08:00
2024-12-05 16:25:46 +08:00
}
2024-12-12 23:03:57 +08:00
await Task.Delay(100); // 延迟,避免过于频繁地检测
2024-12-05 16:25:46 +08:00
}
else
{
return;
}
}
}
2024-12-12 23:03:57 +08:00
2024-12-25 23:08:05 +08:00
/*public void attack(Role targetRole)
2024-12-05 16:25:46 +08:00
{
2024-12-14 23:20:36 +08:00
2024-12-12 23:03:57 +08:00
if (bulletPrefab == null)
2024-12-05 16:25:46 +08:00
{
2024-12-12 23:03:57 +08:00
Debug.LogError("子弹预制体为空");
2024-12-05 16:25:46 +08:00
return;
}
2024-12-12 17:06:08 +08:00
2024-12-14 23:20:36 +08:00
2024-12-05 16:25:46 +08:00
Vector2 direction = (targetRole.transform.position - transform.position).normalized;
2024-12-12 23:03:57 +08:00
if (bulletPrefab.GetComponent<Bullet>().myBulletType == BulletType.Spraying)
{
2024-12-05 16:25:46 +08:00
GameObject BulletGamobj = GameObject.Instantiate(bulletPrefab, this.transform.root);
BulletGamobj.GetComponent<Bullet>().role = role;
2024-12-12 23:03:57 +08:00
BulletGamobj.GetComponent<Bullet>().attackObj = this;
// BulletGamobj.transform.up = direction;
2024-12-17 17:15:32 +08:00
BulletGamobj.transform.position =new Vector2(transform.position.x+0.15f, transform.position.y+0.2f);
2024-12-05 16:25:46 +08:00
bulltes.Add(BulletGamobj);
2024-12-12 23:03:57 +08:00
return;
}
else
{
for (int i = 0; i < bulletData.BulletScattering; i++)
{
// 改变子弹方向,根据角色自身的攻击范围来计算
GameObject BulletGamobj = GameObject.Instantiate(bulletPrefab, this.transform.root);
BulletGamobj.GetComponent<Bullet>().role = role;
BulletGamobj.GetComponent<Bullet>().attackObj = this;
BulletGamobj.transform.up = direction;
BulletGamobj.transform.position = transform.position;
bulltes.Add(BulletGamobj);
}
}
2024-12-25 23:08:05 +08:00
}*/
2024-12-17 18:07:43 +08:00
public void Pointattack()
{
if (bulletPrefab == null)
{
Debug.LogError("子弹预制体为空");
return;
}
2024-12-25 23:08:05 +08:00
for (int i = 0; i < BulletNumber; i++)
{
// 改变子弹方向,根据角色自身的攻击范围来计算
GameObject BulletGamobj = GameObject.Instantiate(bulletPrefab, this.transform.root);
BulletGamobj.GetComponent<Bullet>().role = role;
BulletGamobj.GetComponent<Bullet>().attackObj = this;
BulletGamobj.GetComponent<Bullet>().bulletData.BulletSpeed *= (1 + roleBulletSpeedAdd);
BulletGamobj.transform.up = direction;
BulletGamobj.transform.position = BulletStartPos.position;
bulltes.Add(BulletGamobj);
}
2024-12-17 18:07:43 +08:00
}
2024-12-12 23:03:57 +08:00
2024-12-17 17:15:32 +08:00
public void Fireattack()
{
if (bulletPrefab == null)
{
Debug.LogError("子弹预制体为空");
return;
}
2024-12-26 11:19:45 +08:00
// 检查子弹类型是否为 Spraying
2024-12-17 17:15:32 +08:00
if (bulletPrefab.GetComponent<Bullet>().myBulletType == BulletType.Spraying)
{
2024-12-26 11:19:45 +08:00
// 根据 BulletNumber 生成不同数量和旋转角度的子弹
switch (BulletNumber)
2024-12-25 23:08:05 +08:00
{
2024-12-26 11:19:45 +08:00
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;
}
}
}
2024-12-25 23:08:05 +08:00
2024-12-26 11:19:45 +08:00
private void GenerateBullet(float angle, Vector2 startPos, Vector2 changePos)//角度,旋转中心点
{
// 实例化子弹对象并设置父物体为 transform.root
GameObject bulletGameObj = GameObject.Instantiate(bulletPrefab, transform.root);
2024-12-25 23:08:05 +08:00
2024-12-26 11:19:45 +08:00
// 获取动画组件(如果需要的话)
fireAnis.Add(bulletGameObj.GetComponentInChildren<Animator>());
2024-12-25 23:08:05 +08:00
2024-12-26 11:19:45 +08:00
// 设置子弹的初始位置,保持偏移量
2024-12-26 18:11:09 +08:00
bulletGameObj.transform.position = new Vector2(transform.position.x+1.75f, transform.position.y + 0.2f);
2024-12-25 23:08:05 +08:00
2024-12-26 18:11:09 +08:00
bulletGameObj.GetComponent<Bullet>().role = role;
bulletGameObj.GetComponent<Bullet>().attackObj = this;
2024-12-26 11:19:45 +08:00
// 计算子弹相对于旋转中心的偏移
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);
2024-12-17 17:15:32 +08:00
}
2024-12-26 11:19:45 +08:00
2024-12-17 17:15:32 +08:00
public void EndFire()
{
2024-12-26 11:19:45 +08:00
foreach (Animator ani in fireAnis)
{
ani.SetInteger("State", 1);
}
fireAnis.Clear();
2024-12-24 17:40:22 +08:00
//Debug.Log("停止火焰");
2024-12-17 17:15:32 +08:00
}
2024-12-12 23:03:57 +08:00
private void OnDisable()
{
bulltes.Clear();
2024-12-05 16:25:46 +08:00
}
2024-12-23 14:28:04 +08:00
2024-12-26 18:11:09 +08:00
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);
2024-12-23 14:28:04 +08:00
2024-12-26 18:11:09 +08:00
}
2024-12-05 16:25:46 +08:00
}