using Photon.Pun; 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 PhotonView photonView; public PhotonView owner; 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 PhotonView possibleTarget; 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() { photonView = GetComponent(); onTargetHit.AddListener(SpawnHitParticleVFX); } public virtual void Init() { waitingForDestroy = false; if (photonView.IsMine) { relocatedHitBox = hitBox.transform.localPosition; resizedByAbility = hitBox.transform.localScale; resizedByAbility.z = range; relocatedHitBox.z = range / 2; hitBox.transform.localScale = resizedByAbility; hitBox.transform.localPosition = relocatedHitBox; photonView.RPC(nameof(RPC_RemoteInit), RpcTarget.Others, AbilityIndexer.Instance.Abilities.IndexOf(ability)); ownerHealth = owner.GetComponent(); ownerMana = owner.GetComponent(); StartCoroutine(SelfDestruct()); CheckSurroundings(); } } [PunRPC] protected virtual void RPC_RemoteInit(int abilityIndex) { ability = (SimpleMeleeSlashAbility)AbilityIndexer.Instance.Abilities[abilityIndex]; } [PunRPC] protected virtual void RPC_DisableVisuals() { visuals.SetActive(false); } 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); possibleTarget = collider.GetComponentInParent(); if (possibleTarget != null) if (possibleTarget == owner) continue; 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); } if (!photonView.IsMine) return; 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); photonView.RPC(nameof(RPC_DisableVisuals), RpcTarget.Others); yield return new WaitForSeconds(1.5f); for (int i = hitSpawnedVFXs.Count - 1; i >= 0; i--) { Destroy(hitSpawnedVFXs[i]); } yield return new WaitForSeconds(1f); PhotonNetwork.Destroy(photonView); } protected virtual IEnumerator SelfDestruct() { yield return new WaitForSeconds(lifeSpan); waitingForDestroy = true; StartCoroutine(DelayedDestroy()); } }