UnityCommon/Role/Attack.cs
2024-12-26 18:11:09 +08:00

291 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<GameObject> bulltes = new List<GameObject>();
[Header("角色动画控制器")] public Animator animator;
//[Header("火焰动画控制器")] public Animator fireAni;
[Header("火焰动画控制器")] public List<Animator> 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<CircleCollider2D>().radius = attackScope;
// //Debug.Log("攻击半径"+GetComponent<CircleCollider2D>().radius);
// }
//}
public async void Start()
{
//AttackScope = attackScope;
bulletData = new BulletData();
bulletData.BulletScattering = 1;
animator.SetFloat("AttackSpeed",AttackSpeed);
//CircleCollider2D circleCollider2D = GetComponent<CircleCollider2D>();
attackCooldown = transform.parent.GetComponent<enemy>().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<Role>();
if (targetRole && targetRole.camp != role.camp)
{
role.animationHighlight = 1;
if (animator!=null)
{
if (bulletPrefab.GetComponent<Bullet>().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<Bullet>().myBulletType == BulletType.Spraying)
{
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 =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<Bullet>().role = role;
BulletGamobj.GetComponent<Bullet>().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<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);
}
}
public void Fireattack()
{
if (bulletPrefab == null)
{
Debug.LogError("子弹预制体为空");
return;
}
// 检查子弹类型是否为 Spraying
if (bulletPrefab.GetComponent<Bullet>().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<Animator>());
// 设置子弹的初始位置,保持偏移量
bulletGameObj.transform.position = new Vector2(transform.position.x+1.75f, transform.position.y + 0.2f);
bulletGameObj.GetComponent<Bullet>().role = role;
bulletGameObj.GetComponent<Bullet>().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);
}
}