using RaceFields.Damage; using RaceFields.Damage.VehicleDamage; using UnityEngine; public sealed class BulletProjectile : MonoBehaviour { [SerializeField] private float damage = 8f; [SerializeField] private float impactForce = 25f; [SerializeField] private float lifeTime = 2.5f; private Transform ownerRoot; private Rigidbody body; private bool hasHit; private void Awake() { body = GetComponent(); } private void OnEnable() { hasHit = false; } public void Launch(Vector3 velocity, float shotDamage, float shotLifeTime, Transform owner) { damage = shotDamage; lifeTime = Mathf.Max(0.05f, shotLifeTime); ownerRoot = owner != null ? owner.root : null; if (body == null) body = GetComponent(); if (body != null) body.linearVelocity = velocity; Destroy(gameObject, lifeTime); } private void OnCollisionEnter(Collision collision) { if (collision.collider == null) return; Vector3 point = collision.contactCount > 0 ? collision.GetContact(0).point : transform.position; HandleHit(collision.collider, point, body != null ? body.linearVelocity.normalized : transform.forward, collision.rigidbody); } private void OnTriggerEnter(Collider other) { HandleHit(other, transform.position, body != null ? body.linearVelocity.normalized : transform.forward, other.attachedRigidbody); } private void HandleHit(Collider hitCollider, Vector3 point, Vector3 direction, Rigidbody hitBody) { if (hasHit || hitCollider == null) return; if (ownerRoot != null && hitCollider.transform.root == ownerRoot) return; hasHit = true; DamageHitbox hitbox = hitCollider.GetComponentInParent(); if (hitbox != null) { hitbox.ApplyDamage(new DamageHit(damage, DamageType.Projectile, point, direction, gameObject)); } else { SimpleDamageReceiver damageReceiver = hitCollider.GetComponentInParent(); if (damageReceiver != null) damageReceiver.ApplyDamage(damage, point, direction, gameObject); } if (hitBody != null && (ownerRoot == null || hitBody.transform.root != ownerRoot)) hitBody.AddForceAtPosition(direction * impactForce, point, ForceMode.Impulse); Destroy(gameObject); } }