using Invector; using Invector.vCharacterController; using UnityEngine; namespace DemonBoss.Magic { /// /// Component that adds damage when the player gets too close to the shield. /// Add to the shield object along with Sphere Collider (IsTrigger = true). /// public class ShieldDamage : MonoBehaviour { [Header("Damage Configuration")] [Tooltip("Damage dealt to the player")] public int damage = 15; [Tooltip("Knockback force")] public float knockbackForce = 10f; [Tooltip("Player Tag")] public string playerTag = "Player"; [Tooltip("Time between consecutive hits (so as not to deal damage to every frame)")] public float damageInterval = 1f; [Header("Effects")] [Tooltip("Sound effect when dealing damage")] public AudioClip damageSound; [Tooltip("Visual effect when dealing damage")] public GameObject damageEffect; [Header("Debug")] [Tooltip("Enable debug logs")] public bool enableDebug = false; private AudioSource audioSource; private float lastDamageTime; private void Awake() { if (damageSound != null) { audioSource = GetComponent(); if (audioSource == null) { audioSource = gameObject.AddComponent(); audioSource.playOnAwake = false; audioSource.spatialBlend = 1f; // 3D sound } } } private void OnTriggerStay(Collider other) { if (other.CompareTag(playerTag) && Time.time >= lastDamageTime + damageInterval) { DealDamageToPlayer(other); lastDamageTime = Time.time; } } private void DealDamageToPlayer(Collider playerCollider) { if (enableDebug) Debug.Log($"[ShieldDamage] I deal {damage} damage to the player: {playerCollider.name}"); Vector3 hitPoint = playerCollider.ClosestPoint(transform.position); Vector3 hitDirection = (playerCollider.transform.position - transform.position).normalized; vDamage damageInfo = new vDamage(damage) { sender = transform, hitPosition = hitPoint }; if (knockbackForce > 0f) { damageInfo.force = hitDirection * knockbackForce; } bool damageDealt = false; // 1) vIDamageReceiver var damageReceiver = playerCollider.GetComponent() ?? playerCollider.GetComponentInParent(); if (damageReceiver != null) { damageReceiver.TakeDamage(damageInfo); damageDealt = true; if (enableDebug) Debug.Log("[ShieldDamage] Damage dealt by vIDamageReceiver"); } // 2) vHealthController if (!damageDealt) { var healthController = playerCollider.GetComponent() ?? playerCollider.GetComponentInParent(); if (healthController != null) { healthController.TakeDamage(damageInfo); damageDealt = true; if (enableDebug) Debug.Log("[ShieldDamage] Damage dealt by vHealthController"); } } // 3) vThirdPersonController if (!damageDealt) { var tpc = playerCollider.GetComponent() ?? playerCollider.GetComponentInParent(); if (tpc != null) { // SprawdŸ czy to Beyond variant if (tpc is Beyond.bThirdPersonController beyond) { if (!beyond.GodMode && !beyond.isImmortal) { tpc.TakeDamage(damageInfo); damageDealt = true; if (enableDebug) Debug.Log("[ShieldDamage] Damage dealt by bThirdPersonController"); } else { if (enableDebug) Debug.Log("[ShieldDamage] Player is immortal - no damage"); } } else { tpc.TakeDamage(damageInfo); damageDealt = true; if (enableDebug) Debug.Log("[ShieldDamage] Damage dealt by vThirdPersonController"); } } } if (damageDealt) { PlayEffects(hitPoint); } else if (enableDebug) { Debug.LogWarning("[ShieldDamage] Cannot deal damage - missing required component!"); } } private void PlayEffects(Vector3 hitPoint) { // Play hit sound if (audioSource != null && damageSound != null) { audioSource.PlayOneShot(damageSound); } // Show visual effect if (damageEffect != null) { GameObject effect = Instantiate(damageEffect, hitPoint, Quaternion.identity); Destroy(effect, 2f); // Remove after 2 seconds } } #if UNITY_EDITOR /// /// Draw damage range visualization in Scene View /// private void OnDrawGizmosSelected() { // Show damage range Collider col = GetComponent(); if (col != null && col.isTrigger) { Gizmos.color = Color.red; if (col is SphereCollider sphere) { Gizmos.DrawWireSphere(transform.position, sphere.radius); } else if (col is CapsuleCollider capsule) { // Approximate capsule visualization Gizmos.DrawWireSphere(transform.position, capsule.radius); } } } #endif } }