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.EquipShield(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;
            }
        }
        // PROPERTIES: ----------------------------------------------------------------------------



        // INITIALIZER: ---------------------------------------------------------------------------

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

            this.sectionGeneral = new Section("General", this.LoadIcon("General"), this.Repaint);
            this.sectionModel   = new Section("Weapon Model", this.LoadIcon("Sword"), this.Repaint);
            this.sectionEffects = new Section("Effects", this.LoadIcon("Effects"), this.Repaint);

            this.spName        = this.serializedObject.FindProperty("weaponName");
            this.spDescription = this.serializedObject.FindProperty("weaponDescription");

            this.spDefaultShield  = this.serializedObject.FindProperty("defaultShield");
            this.spCharacterState = this.serializedObject.FindProperty("characterState");
            this.spAvatarMask     = this.serializedObject.FindProperty("characterMask");

            this.spPrefab     = this.serializedObject.FindProperty("prefab");
            this.spAttachment = this.serializedObject.FindProperty("attachment");
            this.spPosition   = this.serializedObject.FindProperty("positionOffset");
            this.spRotation   = this.serializedObject.FindProperty("rotationOffset");

            this.spAudioSheathe         = this.serializedObject.FindProperty("audioSheathe");
            this.spAudioDraw            = this.serializedObject.FindProperty("audioDraw");
            this.spAudioImpactNormal    = this.serializedObject.FindProperty("audioImpactNormal");
            this.spAudioImpactKnockback = this.serializedObject.FindProperty("audioImpactKnockback");

            this.spPrefabImpactNormal    = this.serializedObject.FindProperty("prefabImpactNormal");
            this.spPrefabImpactKnockback = this.serializedObject.FindProperty("prefabImpactKnockback");

            this.spGroundHitReactionFront    = this.serializedObject.FindProperty("groundHitReactionsFront");
            this.spGroundHitReactionBehind   = this.serializedObject.FindProperty("groundHitReactionsBehind");
            this.spAirborneHitReactionFront  = this.serializedObject.FindProperty("airborneHitReactionsFront");
            this.spAirborneHitReactionBehind = this.serializedObject.FindProperty("airborneHitReactionsBehind");
            this.spKnockbackReactions        = this.serializedObject.FindProperty("knockbackReaction");

            this.groundHitReactionsFrontList = new ReorderableList(
                this.serializedObject,
                this.spGroundHitReactionFront,
                true, true, true, true
                );

            this.groundHitReactionsBehindList = new ReorderableList(
                this.serializedObject,
                this.spGroundHitReactionBehind,
                true, true, true, true
                );

            this.airborneHitReactionsFrontList = new ReorderableList(
                this.serializedObject,
                this.spAirborneHitReactionFront,
                true, true, true, true
                );

            this.airborneHitReactionsBehindList = new ReorderableList(
                this.serializedObject,
                this.spAirborneHitReactionBehind,
                true, true, true, true
                );

            this.knockbackReactionsList = new ReorderableList(
                this.serializedObject,
                this.spKnockbackReactions,
                true, true, true, true
                );

            this.groundHitReactionsFrontList.drawHeaderCallback    += this.PaintHitGroundFront_Title;
            this.groundHitReactionsBehindList.drawHeaderCallback   += this.PaintHitGroundBehind_Title;
            this.airborneHitReactionsFrontList.drawHeaderCallback  += this.PaintHitAirFront_Title;
            this.airborneHitReactionsBehindList.drawHeaderCallback += this.PaintHitAirBehind_Title;
            this.knockbackReactionsList.drawHeaderCallback         += this.PaintKnockback_Title;

            this.groundHitReactionsFrontList.drawElementCallback    += this.PaintHitGroundFront_Element;
            this.groundHitReactionsBehindList.drawElementCallback   += this.PaintHitGroundBehind_Element;
            this.airborneHitReactionsFrontList.drawElementCallback  += this.PaintHitAirFront_Element;
            this.airborneHitReactionsBehindList.drawElementCallback += this.PaintHitAirBehind_Element;
            this.knockbackReactionsList.drawElementCallback         += this.PaintHitKnockback_Element;

            this.spCombos = this.serializedObject.FindProperty("combos");

            this.comboList = new ReorderableList(
                this.serializedObject,
                this.spCombos,
                true, true, true, true
                );

            this.comboList.elementHeight                  = ComboPD.GetHeight() + PADDING * 2F;
            this.comboList.drawHeaderCallback            += this.PaintCombo_Header;
            this.comboList.drawElementBackgroundCallback += this.PaintCombo_ElementBg;
            this.comboList.drawElementCallback           += this.PaintCombo_Element;
        }
        // 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);
            }
            if (this.modelShield != null)
            {
                Destroy(this.modelShield);
            }

            this.OnSheatheWeapon();

            yield return(wait);

            this.IsSheathing = false;

            this.previousWeapon = this.currentWeapon;
            this.previousShield = this.currentShield;

            this.currentWeapon = null;
            this.currentShield = null;

            this.comboSystem = null;

            this.Character.characterLocomotion.isBusy = false;
        }