using UnityEngine; public class Projectile : MonoBehaviour { private GameObject target; private GameObject owner; private float damage; private float speed; private float lifetime; private bool initialized; public void Initialize( GameObject targetObject, float damageAmount, GameObject ownerObject, float moveSpeed, float lifeTime) { target = targetObject; damage = damageAmount; owner = ownerObject; speed = moveSpeed; lifetime = lifeTime; initialized = true; if (lifetime > 0f) { Destroy(gameObject, lifetime); } } private void Update() { if (!initialized) { return; } if (target == null) { Destroy(gameObject); return; } Vector3 offset = target.transform.position - transform.position; if (offset.sqrMagnitude <= 0.01f) { HitTarget(target); return; } Vector3 direction = offset.normalized; float distance = speed * Time.deltaTime; if (distance >= offset.magnitude) { HitTarget(target); return; } if (Physics.Raycast(transform.position, direction, out RaycastHit hit, distance)) { TryHit(hit.collider.gameObject); if (hit.collider.transform.root == target.transform.root) { return; } } transform.forward = direction; transform.position += direction * distance; } private void OnTriggerEnter(Collider other) { TryHit(other.gameObject); } private void OnCollisionEnter(Collision collision) { TryHit(collision.gameObject); } private void TryHit(GameObject hitObject) { if (!initialized || hitObject == null || IsOwner(hitObject)) { return; } if (hitObject.transform.root == target.transform.root) { HitTarget(hitObject); } } private void HitTarget(GameObject hitObject) { WorldHealthBar healthBar = hitObject.GetComponentInParent(); if (healthBar == null) { return; } healthBar.TakeDamage(damage); if (owner != null) { UnitBase unit = owner.GetComponent(); if (unit != null) { unit.RegisterAttackHit(); } } Destroy(gameObject); } private bool IsOwner(GameObject hitObject) { return owner != null && (hitObject == owner || hitObject.transform.root == owner.transform.root); } }