Demon Fixes
This commit is contained in:
191
Assets/AI/Demon/ShieldDamage.cs
Normal file
191
Assets/AI/Demon/ShieldDamage.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using Invector;
|
||||
using Invector.vCharacterController;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DemonBoss.Magic
|
||||
{
|
||||
/// <summary>
|
||||
/// Component that adds damage when the player gets too close to the shield.
|
||||
/// Add to the shield object along with Sphere Collider (IsTrigger = true).
|
||||
/// </summary>
|
||||
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<AudioSource>();
|
||||
if (audioSource == null)
|
||||
{
|
||||
audioSource = gameObject.AddComponent<AudioSource>();
|
||||
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<vIDamageReceiver>() ??
|
||||
playerCollider.GetComponentInParent<vIDamageReceiver>();
|
||||
|
||||
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<vHealthController>() ??
|
||||
playerCollider.GetComponentInParent<vHealthController>();
|
||||
|
||||
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<vThirdPersonController>() ??
|
||||
playerCollider.GetComponentInParent<vThirdPersonController>();
|
||||
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Draw damage range visualization in Scene View
|
||||
/// </summary>
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
// Show damage range
|
||||
Collider col = GetComponent<Collider>();
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user