// CALLBACK METHODS: ----------------------------------------------------------------------

        public HitResult OnReceiveAttack(CharacterMelee attacker, MeleeClip attack)
        {
            if (this.currentWeapon == null)
            {
                return(HitResult.ReceiveDamage);
            }
            if (this.IsInvincible)
            {
                return(HitResult.Ignore);
            }

            float attackAngle = Vector3.Angle(
                attacker.transform.TransformDirection(Vector3.forward),
                this.transform.TransformDirection(Vector3.forward)
                );

            float defenseAngle = this.currentShield != null
                ? this.currentShield.defenseAngle.GetValue(gameObject)
                : 0f;

            if (this.currentShield != null &&
                attack.isBlockable && this.IsBlocking &&
                180f - attackAngle < defenseAngle / 2f)
            {
                this.AddDefense(-attack.defenseDamage);
                if (this.Defense > 0)
                {
                    if (Time.time < this.startBlockingTime + this.currentShield.perfectBlockWindow)
                    {
                        if (attacker != null)
                        {
                            MeleeClip attackerReaction = this.Character.IsGrounded()
                                ? this.currentShield.groundPerfectBlockReaction
                                : this.currentShield.airbornPerfectBlockReaction;

                            attackerReaction.Play(attacker);
                        }

                        if (this.currentShield.perfectBlockClip != null)
                        {
                            this.currentShield.perfectBlockClip.Play(this);
                        }

                        this.ExecuteEffects(
                            this.blade.GetImpactPosition(),
                            this.currentShield.audioPerfectBlock,
                            this.currentShield.prefabImpactPerfectBlock
                            );

                        this.comboSystem.OnPerfectBlock();
                        return(HitResult.PerfectBlock);
                    }

                    MeleeClip blockReaction = this.currentShield.GetBlockReaction();
                    if (blockReaction != null)
                    {
                        blockReaction.Play(this);
                    }

                    this.ExecuteEffects(
                        this.blade.GetImpactPosition(),
                        this.currentShield.audioBlock,
                        this.currentShield.prefabImpactBlock
                        );

                    this.comboSystem.OnBlock();
                    return(HitResult.AttackBlock);
                }
                else
                {
                    this.Defense = 0f;
                    this.StopBlocking();

                    if (this.EventBreakDefense != null)
                    {
                        this.EventBreakDefense.Invoke();
                    }
                }
            }

            this.AddPoise(-attack.poiseDamage);
            bool isFrontalAttack = attackAngle >= 90f;
            bool isKnockback     = this.Poise <= float.Epsilon;

            MeleeClip hitReaction = this.currentWeapon.GetHitReaction(
                this.Character.IsGrounded(),
                isFrontalAttack,
                isKnockback
                );

            this.ExecuteEffects(
                attacker.blade.GetImpactPosition(),
                isKnockback
                    ? this.currentWeapon.audioImpactKnockback
                    : this.currentWeapon.audioImpactNormal,
                isKnockback
                    ? this.currentWeapon.prefabImpactKnockback
                    : this.currentWeapon.prefabImpactNormal
                );

            attack.ExecuteHitPause();
            if (!this.IsUninterruptable)
            {
                hitReaction.Play(this);
            }

            return(HitResult.ReceiveDamage);
        }