// PUBLIC METHODS: ------------------------------------------------------------------------

        public IEnumerator Sheathe()
        {
            if (this.Character.characterLocomotion.isBusy)
            {
                yield break;
            }
            if (!this.CanAttack())
            {
                yield break;
            }
            if (this.IsAttacking)
            {
                yield break;
            }

            this.ReleaseTargetFocus();

            WaitForSeconds wait = new WaitForSeconds(0f);

            if (this.currentWeapon != null)
            {
                if (this.currentWeapon.characterState != null)
                {
                    CharacterState currentState = this.CharacterAnimator.GetState(MeleeWeapon.LAYER_STANCE);
                    if (currentState != null)
                    {
                        float time = this.ResetState(currentState, MeleeWeapon.LAYER_STANCE);
                        wait = new WaitForSeconds(time);
                    }
                }

                this.PlayAudio(this.currentWeapon.audioSheathe);
            }

            this.Character.characterLocomotion.isBusy = true;
            this.IsSheathing = true;

            yield return(wait);

            if (this.EventSheatheWeapon != null)
            {
                this.EventSheatheWeapon.Invoke(this.currentWeapon);
            }
            if (this.modelWeapon != null)
            {
                Destroy(this.modelWeapon);
            }

            this.OnSheatheWeapon();

            yield return(wait);

            this.IsSheathing   = false;
            this.currentWeapon = null;
            this.currentShield = null;
            this.comboSystem   = null;

            this.Character.characterLocomotion.isBusy = false;
        }
        public void EquipShield(MeleeShield shield)
        {
            if (shield == null)
            {
                return;
            }

            if (this.modelShield != null)
            {
                Destroy(this.modelShield);
            }

            this.modelShield   = shield.EquipShield(this.CharacterAnimator);
            this.currentShield = shield;
        }
        // INITIALIZER: ---------------------------------------------------------------------------

        private void OnEnable()
        {
            this.instance = this.target as MeleeShield;

            this.sectionGeneral = new Section("General", this.LoadIcon("General"), this.Repaint);
            this.sectionEffects = new Section("Effects", this.LoadIcon("Effects"), this.Repaint);
            this.sectionCombat  = new Section("Combat", this.LoadIcon("Combat"), this.Repaint);

            this.spName        = this.serializedObject.FindProperty("shieldName");
            this.spDescription = this.serializedObject.FindProperty("shieldDescription");

            this.spPrefab         = this.serializedObject.FindProperty("prefab");
            this.spAttachment     = this.serializedObject.FindProperty("attachment");
            this.spPositionOffset = this.serializedObject.FindProperty("positionOffset");
            this.spRotationOffset = this.serializedObject.FindProperty("rotationOffset");

            this.spDefenseState      = this.serializedObject.FindProperty("defendState");
            this.spDefenseMask       = this.serializedObject.FindProperty("defendMask");
            this.spLowerBodyRotation = this.serializedObject.FindProperty("lowerBodyRotation");

            this.spDefenseAngle       = this.serializedObject.FindProperty("defenseAngle");
            this.spPerfectBlockWindow = this.serializedObject.FindProperty("perfectBlockWindow");

            this.spDefenseRecoverRate = this.serializedObject.FindProperty("defenseRecoveryRate");
            this.spMaxDefense         = this.serializedObject.FindProperty("maxDefense");
            this.spDelayDefense       = this.serializedObject.FindProperty("delayDefense");

            this.spPerfectBlockClip            = this.serializedObject.FindProperty("perfectBlockClip");
            this.spBlockHitReactions           = this.serializedObject.FindProperty("blockingHitReaction");
            this.spGroundPerfectBlockReaction  = this.serializedObject.FindProperty("groundPerfectBlockReaction");
            this.spAirbornPerfectBlockReaction = this.serializedObject.FindProperty("airbornPerfectBlockReaction");

            this.spAudioBlock               = this.serializedObject.FindProperty("audioBlock");
            this.spAudioPerfectBlock        = this.serializedObject.FindProperty("audioPerfectBlock");
            this.spPrefabImpactBlock        = this.serializedObject.FindProperty("prefabImpactBlock");
            this.spPrefabImpactPerfectBlock = this.serializedObject.FindProperty("prefabImpactPerfectBlock");

            this.blockHitReactionsList = new ReorderableList(
                this.serializedObject,
                this.spBlockHitReactions,
                true, true, true, true
                );

            this.blockHitReactionsList.drawHeaderCallback  += this.PaintHitBlockReaction_Title;
            this.blockHitReactionsList.drawElementCallback += this.PaintHitBlockReaction_Element;
        }
        public IEnumerator Draw(MeleeWeapon weapon, MeleeShield shield = null)
        {
            if (this.Character.characterLocomotion.isBusy)
            {
                yield break;
            }
            if (this.IsAttacking)
            {
                yield break;
            }
            if (!this.CanAttack())
            {
                yield break;
            }

            yield return(this.Sheathe());

            if (weapon != null)
            {
                this.currentWeapon = weapon;
                this.currentShield = shield != null ? shield : weapon.defaultShield;

                this.comboSystem = new ComboSystem(this, weapon.combos);

                WaitForSeconds wait = new WaitForSeconds(0f);

                if (this.currentWeapon.characterState != null)
                {
                    CharacterState state = this.currentWeapon.characterState;
                    float          time  = this.ChangeState(
                        this.currentWeapon.characterState,
                        this.currentWeapon.characterMask,
                        MeleeWeapon.LAYER_STANCE
                        );

                    if (state.enterClip != null)
                    {
                        wait = new WaitForSeconds(time);
                    }
                }

                this.PlayAudio(this.currentWeapon.audioDraw);

                this.Character.characterLocomotion.isBusy = true;
                this.IsDrawing = true;

                yield return(wait);

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

                this.modelWeapon = this.currentWeapon.EquipWeapon(this.CharacterAnimator);
                this.blade       = this.modelWeapon.GetComponentInChildren <BladeComponent>();
                if (this.blade != null)
                {
                    this.blade.Setup(this);
                }

                this.OnDrawWeapon();

                yield return(wait);

                this.IsDrawing = false;
                this.Character.characterLocomotion.isBusy = false;
            }
        }