using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public class NetworkedSlash : MonoBehaviour { [Header("Visuals")] [SerializeField] protected GameObject hitParticlesPrefab; [SerializeField] protected GameObject visuals; [SerializeField] protected GameObject hitBox; [Header("Physics:")] [SerializeField] protected LayerMask abilityHitLayer; [Header("Set by code")] public Taggable ownerTag; public SimpleMeleeSlashAbility ability; public float lifeSpan; public float range; public bool regenHealthOnHit; public bool regenManaOnHit; public float healthOnHit; public float manaOnHit; protected Health ownerHealth; protected Mana ownerMana; protected Taggable target; protected List targets = new List(); protected bool waitingForDestroy = false; public UnityEvent onTargetHit = new UnityEvent(); protected Vector3 resizedByAbility = new Vector3(); protected Vector3 relocatedHitBox = new Vector3(); protected Collider[] hits; protected List hitSpawnedVFXs = new List(); protected GameObject hitSpawnedVFX; protected Vector3 hitPositionCorrected; protected virtual void Awake() { onTargetHit.AddListener(SpawnHitParticleVFX); } public virtual void Init() { waitingForDestroy = false; relocatedHitBox = hitBox.transform.localPosition; resizedByAbility = hitBox.transform.localScale; resizedByAbility.z = range; relocatedHitBox.z = 0; hitBox.transform.localScale = resizedByAbility; hitBox.transform.localPosition = relocatedHitBox; ownerHealth = ownerTag.GetComponent(); ownerMana = ownerTag.GetComponent(); StartCoroutine(SelfDestruct()); CheckSurroundings(); } protected virtual void SpawnHitParticleVFX(Vector3 position) { if (hitParticlesPrefab == null) return; hitSpawnedVFX = Instantiate(hitParticlesPrefab, position, this.transform.rotation); //hitSpawnedVFX.transform.localScale = visuals.transform.localScale; hitSpawnedVFXs.Add(hitSpawnedVFX); } protected virtual void CheckSurroundings() { hits = Physics.OverlapBox(hitBox.transform.position, hitBox.transform.localScale / 2, this.transform.rotation, abilityHitLayer); foreach (Collider collider in hits) { //Debug.Log("hit collider " + collider.name); if (collider.GetComponent() != null) { collider.GetComponent().Hit(); onTargetHit.Invoke(collider.ClosestPoint(this.transform.position)); } target = collider.GetComponentInParent(); //Debug.Log("hit collider, Got taggable: " + target.name); if (target == null) continue; //Debug.Log("hit collider, targetTag: " + target.targetTag.name); if (!target.IsValidTarget(ability.targettingTags)) continue; hitPositionCorrected = target.transform.position; hitPositionCorrected.y = this.transform.position.y; onTargetHit.Invoke(hitPositionCorrected); //Debug.Log("hit collider, added target: " + target.name); targets.Add(target); } foreach (BaseEffect effect in ability.abilityEffects) { effect.ApplyEffect(ownerTag, targets); } if (regenHealthOnHit) ownerHealth.ChangeValue(healthOnHit * targets.Count); if (regenManaOnHit) ownerMana.ChangeValue(manaOnHit * targets.Count); } protected virtual IEnumerator DelayedDestroy() { visuals.SetActive(false); yield return new WaitForSeconds(1.5f); for (int i = hitSpawnedVFXs.Count - 1; i >= 0; i--) { Destroy(hitSpawnedVFXs[i]); } yield return new WaitForSeconds(1f); Destroy(this.gameObject); } protected virtual IEnumerator SelfDestruct() { yield return new WaitForSeconds(lifeSpan); waitingForDestroy = true; StartCoroutine(DelayedDestroy()); } }