using System; using DragonLi.Core; using DragonLi.Frame; using Mirror; using UnityEngine; public class Bullet : NetworkBehaviour { /// /// 子弹类型 /// #if UNITY_EDITOR [DisplayOnly] #endif public BulletType type; [Header("伤害")] #if UNITY_EDITOR [DisplayOnly] #endif public float damage = 0; [Header("破韧")] #if UNITY_EDITOR [DisplayOnly] #endif public float deToughness = 0; [Header("击中删除时间")] public float despawn_delay = 0.1f; [Header("自动删除时间")] public float auto_despawn_delay = 5f; [Header("撞击预制体")] public GameObject impact_prefab; [Header("撞击删除时间")] public float impact_despawn_time = 1f; [Header("是否使用重力")] public bool use_gravity = false; public bool hit_trigger = false; [Header("目标图层")] public LayerMask HitLayer; #if UNITY_EDITOR [DisplayOnly] #endif public int ownerIndex; private Rigidbody rigidbodyComponent; /// /// 刚体组件 /// public Rigidbody RigidbodyComponent { get { if (rigidbodyComponent == null) { rigidbodyComponent = GetComponentInChildren(); } return rigidbodyComponent; } } private bool _isHit = false; private bool _isValid = true; private float _despawnTime = 0f; private RaycastHit _handlingHit; #region 生命周期 public void Awake() { RigidbodyComponent.useGravity = use_gravity; RigidbodyComponent.constraints = (RigidbodyConstraints)112; } public void OnEnable() { _isHit = false; _isValid = true; _despawnTime = Time.time + auto_despawn_delay; } public void Update() { if (isServer) { if (_isValid) { if (_isHit) { DespawnSelf(); return; } if (_despawnTime < Time.time) { _isValid = false; NetworkServer.Destroy(transform.gameObject); } } } } internal void FixedUpdate() { if (isServer && !_isHit && HitCheck()) { // Debug.Log("撞击"); _isHit = true; SpawnImpact(); ApplyDamage(); } OnFixedUpdate(); } /// /// This will be called when fixedupdate called /// protected virtual void OnFixedUpdate() { } #endregion [Server] public virtual void OnSpawn(int ownerIndex, Vector3 recoil, float recoilCount) { this.ownerIndex = ownerIndex; rigidbodyComponent.velocity = recoil.normalized * recoilCount; rigidbodyComponent.rotation = Quaternion.LookRotation(recoil.normalized); } [Server] public void DespawnSelf() { _isValid = false; CoroutineTaskManager.Instance.WaitSecondTodo(() => { NetworkServer.Destroy(transform.gameObject); }, despawn_delay); } [Server] public virtual void SpawnImpact() { if (impact_prefab != null) { GameObject impact = Instantiate(impact_prefab); Debug.Log("生成击中点"); impact.transform.position = _handlingHit.point; NetworkServer.Spawn(impact); CoroutineTaskManager.Instance.WaitSecondTodo(() => { NetworkServer.Destroy(impact); }, impact_despawn_time); // 碰撞点的法线方向 Vector3 normal = _handlingHit.normal; // 在这里处理特效的生成和方向 // 计算特效的旋转方向,使用法线信息 Quaternion rotation = Quaternion.LookRotation(normal); // 将特效的旋转方向设置为法线方向 impact.transform.rotation = rotation; } } [Server] public virtual bool HitCheck() { Vector3 position = transform.position; Vector3 velocity = RigidbodyComponent.velocity * Time.deltaTime; if (Physics.Raycast(position, velocity, out _handlingHit, velocity.magnitude, HitLayer)) { if (hit_trigger && _handlingHit.collider.isTrigger) { return false; } return true; } return false; } [Server] public virtual void ApplyDamage() { // IDamagable component = _handlingHit.transform.GetComponent(); IDamagable component = _handlingHit.transform.GetComponent(); if (component != null) { OnApplyDamage(component); } Player hitPlayer = _handlingHit.transform.GetComponentInParent(); if (hitPlayer != null) { OnHitPlayer(hitPlayer.index); } } [Server] public virtual void OnApplyDamage(IDamagable damagable) { } [Server] public virtual void OnHitPlayer(int index) { } }