| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- using Base.Common;
- using Sirenix.OdinInspector;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Events;
- public enum BulletType
- {
- Single = 0, //单体目标,触发后即销毁
- Penetrate = 1, //穿透,可击中多个目标
- Bomb = 2, //击中目标后爆炸
- Boomerang = 3, //回旋镖
- Throw = 4, //投掷类
- }
- public class Bullet : MonoBehaviour
- {
-
- public bool isBulletMove = true;
-
- [Header("组件")]
- public Character owner;
- public AttackController.AttackMethod attackMethod;
- public Rigidbody rb;
- public List<BeHitTrigger> trigedObjs;
- public BulletType bulletType;
- [ShowIf("@bulletType == BulletType.Throw")]
- public float stopTime;
- [ShowIf("@bulletType == BulletType.Boomerang")]
- [LabelText("回旋镖移动时间")] public float backDuration;
- [ShowIf("@bulletType == BulletType.Boomerang")]
- [LabelText("停留时间")] public float stopDuration;
- [ShowIf("@bulletType == BulletType.Boomerang")]
- [LabelText("坠落速度")] public float extraFallGravity;
- [ShowIf("@bulletType == BulletType.Boomerang")]
- [DisplayOnly] public BoomerangWeaponController BoomerangWeaponController;
- [ShowIf("@bulletType == BulletType.Boomerang")]
- public AttackTrigger attackTrigger;
- [ShowIf("@bulletType == BulletType.Boomerang")]
- public CameraController cameraController;
- [ShowIf("@bulletType == BulletType.Boomerang")]
- public Animator attackAni;
- private Vector3 originalPos;
- public bool isGetTarget = false;
- public float speed;
- public float maxFlyTime = 2f;
- public float flyTime;
- public Character trackTarget;
- [Header("击中特效")]
- public GameObject effect;
- private Vector3 effectPos;
- [Header("未击中,到时长后的消失特效")]
- public GameObject disappearEffect;
- [Header("传送门")]
- public bool canTransmit; //子弹是否能被传送门传送
- public bool haveTransmit; //刚传送过
- [HideInInspector]
- public float transmitTime; //传送CD
- private bool isInVain; //攻击无效
- public UnityAction OnBulletHit;
- [FoldoutGroup("条件")] [LabelText("是否留下箭种")] public bool canStop;
- [FoldoutGroup("条件")] [LabelText("子弹是否追踪")] [Tooltip("不勾选则水平往前射出")] public bool isTrack;
- [FoldoutGroup("条件")] [LabelText("子弹是否始终追踪")] [Tooltip("勾选:子弹会跟着目标转,不勾选:子弹斜着往前直飞")] public bool canAlwaysTrack;
- [FoldoutGroup("条件")] [LabelText("是否由士兵起手式创建")] public bool isCreatedByDemonicSummon = false;
- [FoldoutGroup("条件")] [LabelText("是否能穿过地面")] public bool canPassGround;
- public Vector3 originalScale;
- private Vector3 dir;
- private void Awake()
- {
- rb = GetComponent<Rigidbody>();
- originalScale = transform.localScale;
- }
-
- public virtual void Update()
- {
- if (haveTransmit)
- {
- transmitTime -= Time.deltaTime;
- if (transmitTime <= 0)
- {
- haveTransmit = false;
- }
- }
- }
- private void FixedUpdate()
- {
- if (!isBulletMove)
- {
- return;
- }
- if (bulletType == BulletType.Boomerang && BoomerangWeaponController.isFallDown)
- {
- Vector3 myPos = transform.position;
- if(myPos.y < 0)
- {
- myPos.y = 0;
- rb.useGravity = false;
- rb.velocity = Vector3.zero;
- transform.position = myPos;
- attackAni.gameObject.SetActive(false);
- attackTrigger.gameObject.SetActive(false);
- isInVain = true;
- }
- else
- {
-
- Vector3 velocity = rb.velocity;
- velocity.y += extraFallGravity * Time.deltaTime;
- if(velocity.x > 0.1f)
- {
- velocity.x += extraFallGravity * Time.deltaTime;
- }
- else if(velocity.x < -0.1f)
- {
- velocity.x -= extraFallGravity * Time.deltaTime;
- }
- else
- {
- velocity.x = 0;
- }
- if (transform.position.x <= cameraController.leftBoundary || transform.position.x >= cameraController.rightBoundary)
- {
- velocity.x = 0;
- }
- rb.velocity = velocity;
- }
- return;
- }
- flyTime += Time.deltaTime;
- if (flyTime >= maxFlyTime)
- {
- isGetTarget = true;
- DisappearEffect();
- gameObject.SetActive(false);
- return;
- }
- if (isTrack && trackTarget != null && !trackTarget.isDie && trackTarget.gameObject.activeInHierarchy)
- {
- if (bulletType == BulletType.Boomerang)
- {
- float addTime = backDuration + stopDuration;
- if (flyTime >= addTime)
- {
- if (attackTrigger.gameObject.activeSelf)
- {
- trigedObjs.Clear();
- attackTrigger.gameObject.SetActive(false);
- }
- transform.position = Vector3.Lerp(originalPos, BoomerangWeaponController.transform.position, (flyTime - addTime) /(maxFlyTime - addTime));
- }
- else if(flyTime >= backDuration)
- {
- rb.velocity = Vector3.zero;
- originalPos = transform.position;
- attackTrigger.gameObject.SetActive(true);
- }
- else
- {
- Vector3 velocity ;
- if(transform.position.y > 0.5f)
- {
- velocity = dir * speed * (1 - flyTime / backDuration);
- if(transform.position.x <= cameraController.leftBoundary || transform.position.x >= cameraController.rightBoundary)
- {
- velocity = Vector3.zero;
- }
- }
- else
- {
- velocity = Vector3.zero;
- }
- rb.velocity = velocity;
- }
-
- }
- if (canAlwaysTrack)
- {
- Vector3 tarDir = (trackTarget.beSearchTrigger.transform.position - transform.position).normalized;
- tarDir.z = 0;
- transform.right = Vector3.Lerp(transform.right, -tarDir, 0.2f);
- rb.velocity = Vector3.Lerp(rb.velocity, speed * tarDir, 0.2f);
- }
- }
- }
- public virtual void BeShoot(Character own, Vector3 shootPos = default, Vector3 dir = default, bool aim = false, bool alwaysTrack = false, Character target = null, AttackController.AttackMethod attackMethod = default)
- {
- transform.position = shootPos;
- transform.right = -dir;
- //假如有拖尾渲染器,初始化时清空拖尾效果
- TrailRenderer trailRenderer = GetComponentInChildren<TrailRenderer>();
- if (trailRenderer != null)
- {
- trailRenderer.Clear();
- }
- isTrack = aim;
- rb.velocity = dir * speed;
- this.dir = dir;
- trackTarget = target;
- owner = own;
- if (isTrack && trackTarget != null && !trackTarget.isDie && trackTarget.gameObject.activeInHierarchy)
- {
- Vector3 tarDir = (trackTarget.beSearchTrigger.transform.position - transform.position).normalized;
- tarDir.z = 0;
- transform.right = -tarDir;
- rb.velocity = speed * tarDir;
- }
- gameObject.SetActive(true);
- isGetTarget = false;
- canAlwaysTrack = alwaysTrack;
- flyTime = 0;
- if(EqualityComparer<AttackController.AttackMethod>.Default.Equals(attackMethod,default))
- {
- this.attackMethod = own.attackController.curAttackMethod;
- }
- else
- {
- this.attackMethod = attackMethod;
- }
- if (attackTrigger)
- {
- attackTrigger.owner = owner;
- attackTrigger.attackMethod = attackMethod;
- attackTrigger.gameObject.SetActive(false);
- }
- if (attackAni)
- {
- attackAni.gameObject.SetActive(true);
- }
- isInVain = false;
- }
- private void GetEffectPos(Collider other)
- {
- effectPos = other.bounds.ClosestPoint(transform.position);
- }
- private void OnTriggerEnter(Collider other)
- {
- if (isGetTarget || isInVain /*|| (bulletType == BulletType.Throw && rb.velocity.y > 0)*/)
- {
- return;
- }
- Platform platform = other.GetComponent<Platform>();
- if (platform != null && !platform.canPenetrateBullets)
- {
- if (bulletType == BulletType.Single || bulletType == BulletType.Throw)
- {
- DisappearEffect();
- gameObject.SetActive(false);
- return;
- }
- }
- if(!canPassGround && other.CompareTag("Ground"))
- {
- DisappearEffect();
- gameObject.SetActive(false);
- return;
- }
- BeHitTrigger hitTrigger = other.GetComponent<BeHitTrigger>();
- if (hitTrigger != null)
- {
- bool triged = false;
- for (int i = 0; i < trigedObjs.Count; i++)
- {
- if (trigedObjs[i] == hitTrigger)
- {
- triged = true;
- break;
- }
- }
- if (!triged)
- {
- trigedObjs.Add(hitTrigger);
- if (Util.CheckCanHit(owner.tag, hitTrigger.owner.tag) && !hitTrigger.owner.isDie)
- {
- if (isCreatedByDemonicSummon)
- {
- attackMethod.AddAdditionalEffects();
- //Debug.Log("飞剑起手式命中敌人");
- }
- hitTrigger.BeHit(attackMethod, owner);
- BeHitEffect(other, hitTrigger);
- switch (bulletType)
- {
- case BulletType.Single:
- case BulletType.Throw:
- isGetTarget = true;
- if (canStop && (hitTrigger.owner.CompareTag("Player") || hitTrigger.owner.CompareTag("Demonic")))
- {
- rb.velocity = Vector3.zero;
- rb.isKinematic = true;
- GetComponent<Collider>().enabled = false;
- transform.parent = hitTrigger.transform;
- BulletStop bs = GetComponent<BulletStop>();
- if (bs)
- {
- bs.enabled = true;
- }
- else
- {
- bs = gameObject.AddComponent<BulletStop>();
- }
- bs.SetDisappearTime(stopTime);
- enabled = false;
- }
- else
- {
- if (isBulletMove)
- gameObject.SetActive(false);
- else OnBulletHit?.Invoke();
- }
- break;
- case BulletType.Penetrate:
- break;
- case BulletType.Bomb:
- break;
- default:
- break;
- }
- }
- }
- }
- }
- protected void BeHitEffect(Collider other, BeHitTrigger bht)
- {
- if (effect)
- {
- GetEffectPos(other);
- PoolManager.Instantiate(effect, effectPos, new Quaternion(0, 0, 0, 0));
- }
- }
- private void DisappearEffect()
- {
- if (disappearEffect)
- {
- PoolManager.Instantiate(disappearEffect, transform.position, new Quaternion(0, 0, 0, 0));
- }
- }
- private void OnEnable()
- {
- trigedObjs.Clear();
- }
- }
|