using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; using Unity.VisualScripting; using UnityEngine; using UnityEngine.UIElements; using System.Linq; public enum BulletType { Bullet, Lightning, Spraying, //原地喷射 XuLi //蓄力攻击 } public enum BulletAttributes { Not, Gold,//金木水火土 Wood, Water, Fire, Earth } public enum BulletMoveType {/// /// 子弹移动方式:点对点, /// PeerToPeer, /// /// 方向移动 /// PointToDirection, Scope } public class BulletData { [Header("子弹穿透次数")] public int NumberOfBulletPenetrations = 1; /// /// 子弹散射次数 /// [Header("子弹散射次数")] public int BulletScattering = 1; [Header("子弹连发次数")] public int BulletBurstTimes = 1; [Header("子弹连发间隔")] public float BulletBurstInterval ; [Header("子弹穿透衰减")] public float BulletPenetrationAttenuation = 0.2f; [Header("子弹飞行速度")] public float BulletSpeed = 5f; [Header("子弹攻击冷却")] public float BulletAttackCooldown = 1f; [Header("子弹伤害")] public float attack = 10; public BulletData() { } public BulletData(int numberOfBulletPenetrations, int bulletScattering, int bulletBurstTimes, float bulletBurstInterval, float bulletPenetrationAttenuation, float bulletSpeed, float bulletAttackCooldown) { NumberOfBulletPenetrations = numberOfBulletPenetrations; BulletScattering = bulletScattering; BulletBurstTimes = bulletBurstTimes; BulletBurstInterval = bulletBurstInterval; BulletPenetrationAttenuation = bulletPenetrationAttenuation; BulletSpeed = bulletSpeed; BulletAttackCooldown = bulletAttackCooldown; } public override string ToString() { return $"{nameof(NumberOfBulletPenetrations)}: {NumberOfBulletPenetrations}, {nameof(BulletScattering)}: {BulletScattering}, {nameof(BulletBurstTimes)}: {BulletBurstTimes}, {nameof(BulletBurstInterval)}: {BulletBurstInterval}, {nameof(BulletPenetrationAttenuation)}: {BulletPenetrationAttenuation}, {nameof(BulletSpeed)}: {BulletSpeed}, {nameof(BulletAttackCooldown)}: {BulletAttackCooldown}"; } } public class Bullet : MonoBehaviour { [Header("子弹发射角色对象")] public Role role; [Header("子弹发射范围对象")] public Attack attackObj; [Header("子弹类型")] public BulletType myBulletType; [Header("子弹属性")] public BulletAttributes bulletAttributes; [Header("攻击类型")] public BulletMoveType bulletMoveType; [Header("子弹数据")] public BulletData bulletData = new BulletData(); [Header("销毁时间,默认是10f")] public float BulletDeadTimer = 10f; [Header("子弹动画")] public Animator animator; [Header("子弹移动参数")] public bool IsMove = true; [Header("子弹碰撞体")] public CircleCollider2D Collider2D; [Header("子弹特效预制体")] public List effectPres = new List(); public float timer = 0; [Header("子弹攻击数量")] public int NumberOfBulletAttacks = 1; [Header("攻击目标")] public GameObject Target; [Header("子弹是否不锁定目标")] public bool noLockEnemy=false; [Header("子弹是否会分裂")] public bool Cansplit = false; [Header("分裂子弹的预制体")] public GameObject smallBulletPrefab; [Header("子弹是否会爆炸")] public bool CanBoom = false; private void Update() { switch (this.bulletMoveType) { //更具子弹的移动方式来移动 case BulletMoveType.PeerToPeer: if (IsMove) { if (Target != null&&Target.activeSelf==true&&!noLockEnemy) { this.gameObject.transform.position = Vector3.MoveTowards(this.gameObject.transform.position, Target.transform.position, Time.deltaTime * bulletData.BulletSpeed); } else { this.gameObject.transform.Translate(Vector3.up * Time.deltaTime * bulletData.BulletSpeed); } timer += Time.deltaTime; if (timer > BulletDeadTimer) { attackObj.bulltes.Remove(this.gameObject); Debug.Log("对象已成功移除。当前列表数量:" + attackObj.bulltes.Count); Destroy(this.gameObject); } } break; case BulletMoveType.PointToDirection: break; case BulletMoveType.Scope: break; } } private void OnTriggerEnter2D(Collider2D collision) { Role Crole = collision.gameObject.GetComponent(); if (Crole) { if (Crole.camp != role.camp) { if (NumberOfBulletAttacks < 0) { return; } else { if (this.myBulletType== BulletType.Spraying) { NumberOfBulletAttacks += 1; } NumberOfBulletAttacks -= 1; foreach (var buff in role.storageBuff) { if (!Crole.PlayerBuff.Contains(buff)) { Crole.PlayerBuff.Add(buff); } } Crole.ApplyBuffs(); // Debug.Log(this.role.gameObject.name + "进行攻击计算"); int direction = 0; if (collision.transform.position.x > transform.position.x) //子弹打到敌人左边,飘字显示到右边 { direction = 1; } if (!CanBoom)//判断子弹是否会爆炸 { Crole.bloodLoss(new object[] { Crole, role.DamageCreate(Crole.GetComponent()), attackObj.damageTyp, role }, direction); attackObj.bulltes.Remove(this.gameObject); if (myBulletType != BulletType.Spraying) { if (animator == null) { SplitBullet(); attackObj.bulltes.Remove(this.gameObject); Destroy(this.gameObject); } else { IsMove = false; //停止移动 Collider2D.enabled = false; //关闭碰撞体 transform.position = collision.transform.position; animator.SetTrigger("Boom"); } } } else { if (animator!=null) { IsMove = false; //停止移动 Collider2D.enabled = false; //关闭碰撞体 transform.position = collision.transform.position; animator.SetTrigger("Boom"); } } if (bulletAttributes == BulletAttributes.Not) //无属性 { Crole.FlashRedEffect(); } if (bulletAttributes == BulletAttributes.Fire) //火 { if (effectPres.Count == 1) { GameObject go = Instantiate(effectPres[0], collision.transform); go.transform.position = new Vector2(collision.transform.position.x, collision.transform.position.y + 0.2f); go.GetComponent().bullet = this; Crole.FlashRedEffect(); //Debug.Log("创建火焰"); } } if (bulletAttributes == BulletAttributes.Water) //水 { if (effectPres.Count > 1) { GameObject go = Instantiate(effectPres[Random.Range(0, effectPres.Count - 1)], collision.transform); go.transform.position = new Vector2(collision.transform.position.x, collision.transform.position.y - 0.2f); collision.transform.GetComponent().SlowDown(0.2f, 3f); Crole.FlashRedEffect(1, 3f); } } } } } } private float lastDamageTime = 0f; private void OnTriggerStay2D(Collider2D collision) { Role Crole = collision.gameObject.GetComponent(); if (Crole) { if (Crole.camp != role.camp) { int direction = 0; if (collision.transform.position.x >= transform.position.x)//子弹打到敌人左边,飘字显示到右边 { direction = 1; } if (myBulletType == BulletType.Spraying) { if (Time.time - lastDamageTime > 1f) // 每秒扣一次血 { Crole.bloodLoss(new object[] { Crole, role.DamageCreate( Crole.GetComponent()), attackObj.damageTyp, role }); Crole.FlashRedEffect(); lastDamageTime = Time.time; } } } } } public void DesBullet() { attackObj.bulltes.Remove(this.gameObject); Destroy(this.gameObject); } private void OnTriggerExit2D(Collider2D collision) { //Debug.Log("进入检测范围"); Role Crole = collision.gameObject.GetComponent(); if (Crole) { if (Crole.camp != role.camp) { //Debug.Log("对象已成功移除。当前列表数量:" + attackObj.bulltes.Count); if (myBulletType != BulletType.Spraying) { if (animator==null) { attackObj.bulltes.Remove(this.gameObject); Destroy(this.gameObject); } } } } } public void SplitBullet()//子弹分列 { if (Cansplit) { // 获取当前子弹的前进方向 Vector3 currentDirection = transform.forward; // 根据生成的数量来生成小子弹 for (int i = 0; i < attackObj.splitNum; i++) { // 在当前方向上随机生成偏移量 Vector3 randomOffset = new Vector3(Random.Range(-0.2f, 0.2f), Random.Range(-0.2f, 0.2f)); // 生成一个小子弹 GameObject smallBullet = Instantiate(smallBulletPrefab, transform.position, Quaternion.identity); smallBullet.GetComponent().role = role; smallBullet.GetComponent().attackObj=attackObj; smallBullet.GetComponent().Target = Target; // 为小子弹设置飞行方向(当前方向 + 随机偏移) smallBullet.transform.up = currentDirection+randomOffset; // 处理小子弹的相关逻辑,例如攻击属性、生命周期等 } } } public void BulletBoom() // 子弹爆炸 { // 扩展碰撞体的大小,模拟爆炸范围 float explosionRadius = attackObj.BoomRange; // 设置爆炸的半径大小 // 检测爆炸范围内的敌人 Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(transform.position, explosionRadius); foreach (var enemyCollider in hitEnemies) { Role enemyRole = enemyCollider.gameObject.GetComponent(); if (enemyRole != null && enemyRole.camp != role.camp) // 如果是敌人并且属于不同的阵营 { // 计算伤害值,可以根据子弹的类型或其他参数来调整 float damage = role.DamageCreate(enemyRole); // 扣血操作 enemyRole.bloodLoss(new object[] { enemyRole, damage, attackObj.damageTyp, role }); enemyRole.FlashRedEffect(); } } // 销毁当前子弹 attackObj.bulltes.Remove(this.gameObject); Destroy(this.gameObject); } void OnDestroy() { // 清理动态加载资源 if (transform.GetComponent() != null) { var material = transform.GetComponent().material; if (material != null) Destroy(material); var texture = material.mainTexture; if (texture != null) Destroy(texture); } // 停止协程 StopAllCoroutines(); // 清理未使用的资源 Resources.UnloadUnusedAssets(); } }