private IEnumerator AttackRoutine() { Timer thisTimer = new Timer(attackDuration); bool didHit = false; isAttacking = true; while (thisTimer.Tick() == false) { yield return(null); } attacked = true; Collider[] hits = Physics.OverlapBox(attackRoot.rotation * new Vector3(attackOffset.x, attackOffset.y, attackOffset.z) + attackRoot.position, attackExtents, attackRoot.rotation, attackableLayers); Damageable victim; for (int i = 0; i < hits.Length; i++) { didHit = true; victim = hits[i].gameObject.GetComponent <Damageable>(); bool canDamage = ((victim is Entity) && ((Entity)victim).isInvulnerable()) ? false : true; // False if victim is an entity and invulnerable if (victim != null && canDamage) { // Invoke a hit event EntityAttackHitEvent e = new EntityAttackHitEvent { entity = this, target = victim }; OnEntityAttackHitEvent?.Invoke(this, e); if (e.cancel == true) { yield break; } // return if the event has been cancelled by any subscriber // Damage the victim and trigger entity hit invulnerability victim.Damage(attackDamage, attackRoot.rotation * new Vector3(attackOffset.x, attackOffset.y, attackOffset.z + attackExtents.z) + attackRoot.position, AttributeChangeCause.ATTACKED, this, attackType); if (victim is Entity) { ((Entity)victim).TriggerHitInvulnerable(); } } } if (didHit == false) { // Invoke a miss event EntityAttackMissEvent e = new EntityAttackMissEvent { entity = this }; OnEntityAttackMissEvent?.Invoke(this, e); if (e.cancel == true) { yield break; } // return if the event has been cancelled by any subscriber } isAttacking = false; while (isAttackReady() == false) { yield return(null); } attacked = false; }
private void OnMiss(object sender, EntityAttackMissEvent e) { // Play a miss sound AudioSource.PlayClipAtPoint(GameMaster.GetAudioDatabase()?.Get("meleeMiss")?.GetClip(), transform.position); }