/// <summary>
        /// Use by the preist to Select a character to Heal, Regen, Attack buff, and defense Buff.
        /// </summary>
        public override void HealPlayers()
        {
            if (hp > 0 && isHealer && target != null && target.layer != MyStaticGameObjects.monsterLayer)
            {
                myCharacterControllerHealingCached = targetMyCharacterStats;
                if (!myCharacterControllerHealingCached.isInDeathTimeout())
                {
                    if (myCharacterControllerHealingCached.GetHp() < myCharacterControllerHealingCached.GetMaxHP())
                    {
                        myCharacterControllerHealingCached.GiveHealth(GetAttackPoint());

                        particle = MyObjectPools.healParticlePoolTransform.GetChild(MyObjectPools.instance.healParticlePool.GetMyObjectIndex()).gameObject;
                        particle.transform.position = targetTransform.position + particleOffset;
                        particle.GetComponent <ParticleSystem>().Play(true);
                    }
                    else if (!myCharacterControllerHealingCached.hasRegen && MyStaticGameObjects.instance.CheckIfAnyMonsterAreInRange())
                    {
                        myCharacterControllerHealingCached.StartRegen(GetAttackPoint());
                    }
                    else if (!myCharacterControllerHealingCached.hasAttackBuff && MyStaticGameObjects.instance.CheckIfAnyMonsterAreInRange())
                    {
                        myCharacterControllerHealingCached.StartAttackBuff(GetAttackPoint());
                    }
                    else if (!myCharacterControllerHealingCached.hasDefenseBuff && MyStaticGameObjects.instance.CheckIfAnyMonsterAreInRange())
                    {
                        myCharacterControllerHealingCached.StartDefenseBuff(GetAttackPoint());
                    }

                    if (weaponAudioSource != null && !weaponAudioSource.audioSource.isPlaying)
                    {
                        weaponAudioSource.Play();
                    }
                }
            }
        }
 /// <summary>
 /// Set the attack target of the companion
 /// </summary>
 /// <param name="theTarget"></param>
 protected internal override void SetTarget(GameObject theTarget)
 {
     if (!isInitialized)
     {
         Init();
     }
     if (target == null && hp > 0)
     {
         IdleAnimation();
     }
     if (!MyCharacterController.isEscaping)
     {
         if (target == theTarget)
         {
             return;
         }
         if (theTarget != null && navMeshAgent.enabled)
         {
             target                 = theTarget;
             targetTransform        = target.transform;
             targetMyCharacterStats = target.GetComponent <MyCharacterStats>();
             // navMeshAgent.ResetPath();
             navMeshAgent.SetDestination(targetTransform.position);
             navMeshAgent.stoppingDistance = monsterAttackStopDistance;
         }
     }
 }
        /// <summary>
        /// Find Healing Target
        /// </summary>
        private void FindHealingTarget()
        {
            if (hp < GetMaxHP() || ((MyStaticGameObjects.instance.CheckIfAnyMonsterAreInRange() && (!hasRegen || !hasAttackBuff || !hasDefenseBuff))))
            {
                SetTarget(gameObject);
            }
            else
            {
                for (int index = 0; index < MyStaticGameObjects.instance.companionsAndPlayer.Length; index++)
                {
                    healingGameObject = MyStaticGameObjects.instance.companionsAndPlayer[index];

                    targetVector2.x = healingGameObject.transform.position.x;
                    targetVector2.y = healingGameObject.transform.position.z;

                    companionVector2.x = theTransform.position.x;
                    companionVector2.y = theTransform.position.z;
                    //           if (healingGameObject != gameObject && Vector3.Distance(healingGameObject.transform.position, theTransform.position) < healingDistance)
                    if (healingGameObject != gameObject && (targetVector2 - companionVector2).sqrMagnitude < healingDistance)
                    {
                        myhealingCharacterStatsCached = healingGameObject.transform.gameObject.GetComponent <MyCharacterStats>();
                        if (!myhealingCharacterStatsCached.isInDeathTimeout())
                        {
                            if (myhealingCharacterStatsCached.GetHp() < myhealingCharacterStatsCached.GetMaxHP() ||
                                ((MyStaticGameObjects.instance.CheckIfAnyMonsterAreInRange() && (!myhealingCharacterStatsCached.hasRegen ||
                                                                                                 !myhealingCharacterStatsCached.hasAttackBuff ||
                                                                                                 !myhealingCharacterStatsCached.hasDefenseBuff))))
                            {
                                SetTarget(healingGameObject.transform.gameObject);
                                break;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// if alive find target and attack or follow the main character if no attack target
        /// if priest will find a companion to heal or follow the main character
        /// </summary>
        void TargetAndMovement()
        {
            if (hp <= 0)
            {
                ResetBuffStats();
                DeathAnimation();
                target          = null;
                targetTransform = null;
                navMeshAgent.ResetPath();
                navMeshAgent.isStopped = true;

                if (!resetingTimeout)
                {
                    resetingTimeout = true;
                    Timing.RunCoroutine(ResetDeathTimeOut());
                }
                return;
            }
            else
            {
                OneSecondInterval();
                CalculateBlogShadowHeight();
                isDead        = false;
                inAttackRange = false;

                resetingTimeout = false;


                if (navMeshAgent.enabled)
                {
                    if (MyCharacterController.isEscaping)
                    {
                        inAttackRange   = false;
                        target          = null;
                        targetTransform = null;
                    }
                    else
                    {
                        if (navMeshAgent.isOnNavMesh && target != null)
                        {
                            targetVector2.x = targetTransform.position.x;
                            targetVector2.y = targetTransform.position.z;

                            companionVector2.x = theTransform.position.x;
                            companionVector2.y = theTransform.position.z;

                            distanceFromTarget = (targetVector2 - companionVector2).sqrMagnitude;


                            if (target.layer == MyStaticGameObjects.monsterLayer && distanceFromTarget <= monsterAttackStopCompareDistance ||
                                target.layer != MyStaticGameObjects.monsterLayer && distanceFromTarget <= healingDistance)
                            {
                                if (isHealer)
                                {
                                    myCharacterStatsCached = targetMyCharacterStats;
                                }
                                if (target.layer == MyStaticGameObjects.monsterLayer)
                                {
                                    yAxisDistance = targetTransform.position.y - theTransform.position.y;
                                    if (yAxisDistance < 0)
                                    {
                                        yAxisDistance = -yAxisDistance;
                                    }
                                    if (targetMyCharacterStats.GetHp() < 1 || !((MyMonsterNavMeshAgent)targetMyCharacterStats).isActive || yAxisDistance > 100)
                                    {
                                        target          = null;
                                        targetTransform = null;

                                        targetMyCharacterStats = null;
                                    }
                                    else
                                    {
                                        navMeshAgent.velocity = zeroVector;
                                        transform.LookAt(targetTransform.position);
                                        AttackAnimation();
                                        inAttackRange          = true;
                                        navMeshAgent.isStopped = true;
                                    }
                                }
                                else if (isHealer &&
                                         (myCharacterStatsCached.GetHp() >= myCharacterStatsCached.GetMaxHP() &&
                                          myCharacterStatsCached.hasRegen &&
                                          myCharacterStatsCached.hasAttackBuff &&
                                          myCharacterStatsCached.hasDefenseBuff
                                         ))
                                {
                                    //heal self
                                    if (hp < GetMaxHP() || !hasRegen || !hasDefenseBuff || !hasDefenseBuff)
                                    {
                                        target                = gameObject;
                                        targetTransform       = target.transform;
                                        navMeshAgent.velocity = zeroVector;
                                        AttackAnimation();
                                        inAttackRange          = true;
                                        navMeshAgent.isStopped = true;
                                    }
                                    else
                                    {
                                        target                 = null;
                                        targetTransform        = null;
                                        targetMyCharacterStats = null;
                                    }
                                }
                                else if (isHealer)
                                {
                                    //heal companions
                                    navMeshAgent.velocity = zeroVector;
                                    transform.LookAt(targetTransform.position);
                                    AttackAnimation();
                                    inAttackRange          = true;
                                    navMeshAgent.isStopped = true;
                                }
                            }
                            else if (distanceFromTarget > maxDistance && target.layer == MyStaticGameObjects.monsterLayer)
                            {
                                target                 = null;
                                targetTransform        = null;
                                targetMyCharacterStats = null;
                                Debug.Log("Monster is out of range.");
                            }
                            else if (previousDestination != targetTransform.position)
                            {
                                navMeshAgent.SetDestination(targetTransform.position);
                                previousDestination = targetTransform.position;
                            }
                        }
                    }

                    if (null == target)
                    {
                        targetVector2.x = playerTransform.position.x;
                        targetVector2.y = playerTransform.position.z;

                        companionVector2.x = theTransform.position.x;
                        companionVector2.y = theTransform.position.z;

                        if ((targetVector2 - companionVector2).sqrMagnitude > 4 || MyCharacterController.isEscaping)
                        {
                            navMeshAgent.SetDestination(playerTransform.position);
                            navMeshAgent.stoppingDistance = playerFollowStopDistance;
                            previousDestination           = playerTransform.position;
                        }
                    }
                }
            }
        }