protected void UpdateFollowTarget()
    {
        // Temp variables
        BaseCharacterEntity   targetEnemy;
        PlayerCharacterEntity targetPlayer;
        NpcEntity             targetNpc;
        ItemDropEntity        targetItemDrop;

        if (TryGetAttackingCharacter(out targetEnemy))
        {
            if (targetEnemy.CurrentHp <= 0)
            {
                queueUsingSkill = null;
                CharacterEntity.SetTargetEntity(null);
                CharacterEntity.StopMove();
                return;
            }

            if (CharacterEntity.IsPlayingActionAnimation())
            {
                CharacterEntity.StopMove();
                return;
            }

            // Find attack distance and fov, from weapon or skill
            var attackDistance = CharacterEntity.GetAttackDistance();
            var attackFov      = CharacterEntity.GetAttackFov();
            if (queueUsingSkill.HasValue)
            {
                var queueUsingSkillValue = queueUsingSkill.Value;
                var characterSkill       = CharacterEntity.Skills[queueUsingSkillValue.skillIndex];
                var skill = characterSkill.GetSkill();
                if (skill != null)
                {
                    if (skill.IsAttack())
                    {
                        attackDistance = CharacterEntity.GetSkillAttackDistance(skill);
                        attackFov      = CharacterEntity.GetSkillAttackFov(skill);
                    }
                    else
                    {
                        // Stop movement to use non attack skill
                        CharacterEntity.StopMove();
                        RequestUsePendingSkill();
                        return;
                    }
                }
                else
                {
                    queueUsingSkill = null;
                }
            }
            var actDistance = attackDistance;
            actDistance -= actDistance * 0.1f;
            actDistance -= StoppingDistance;
            actDistance += targetEnemy.CacheCapsuleCollider.radius;
            if (Vector3.Distance(CharacterTransform.position, targetEnemy.CacheTransform.position) <= actDistance)
            {
                // Stop movement to attack
                CharacterEntity.StopMove();
                var halfFov   = attackFov * 0.5f;
                var targetDir = (CharacterTransform.position - targetEnemy.CacheTransform.position).normalized;
                var angle     = Vector3.Angle(targetDir, CharacterTransform.forward);
                if (angle < 180 + halfFov && angle > 180 - halfFov)
                {
                    // If has queue using skill, attack by the skill
                    if (queueUsingSkill.HasValue)
                    {
                        RequestUsePendingSkill();
                    }
                    else
                    {
                        RequestAttack();
                    }

                    /** Hint: Uncomment these to make it attack one time and stop
                     * //  when reached target and doesn't pressed on mouse like as diablo
                     * if (CacheUISceneGameplay.IsPointerOverUIObject() || !Input.GetMouseButtonUp(0))
                     * {
                     *  queueUsingSkill = null;
                     *  CacheCharacterEntity.SetTargetEntity(null);
                     *  StopPointClickMove();
                     * }
                     */
                }
            }
            else
            {
                UpdateTargetEntityPosition(targetEnemy);
            }
        }
        else if (CharacterEntity.TryGetTargetEntity(out targetPlayer))
        {
            if (targetPlayer.CurrentHp <= 0)
            {
                queueUsingSkill = null;
                CharacterEntity.SetTargetEntity(null);
                CharacterEntity.StopMove();
                return;
            }
            var actDistance = gameInstance.conversationDistance - StoppingDistance;
            if (Vector3.Distance(CharacterTransform.position, targetPlayer.CacheTransform.position) <= actDistance)
            {
                CharacterEntity.StopMove();
                // TODO: do something
            }
            else
            {
                UpdateTargetEntityPosition(targetPlayer);
            }
        }
        else if (CharacterEntity.TryGetTargetEntity(out targetNpc))
        {
            var actDistance = gameInstance.conversationDistance - StoppingDistance;
            if (Vector3.Distance(CharacterTransform.position, targetNpc.CacheTransform.position) <= actDistance)
            {
                CharacterEntity.RequestNpcActivate(targetNpc.ObjectId);
                CharacterEntity.StopMove();
                CharacterEntity.SetTargetEntity(null);
            }
            else
            {
                UpdateTargetEntityPosition(targetNpc);
            }
        }
        else if (CharacterEntity.TryGetTargetEntity(out targetItemDrop))
        {
            var actDistance = gameInstance.pickUpItemDistance - StoppingDistance;
            if (Vector3.Distance(CharacterTransform.position, targetItemDrop.CacheTransform.position) <= actDistance)
            {
                CharacterEntity.RequestPickupItem(targetItemDrop.ObjectId);
                CharacterEntity.StopMove();
                CharacterEntity.SetTargetEntity(null);
            }
            else
            {
                UpdateTargetEntityPosition(targetItemDrop);
            }
        }
    }
    protected void UpdateWASDInput()
    {
        if (CharacterEntity.IsPlayingActionAnimation())
        {
            CharacterEntity.StopMove();
            return;
        }

        var horizontalInput = InputManager.GetAxis("Horizontal", false);
        var verticalInput   = InputManager.GetAxis("Vertical", false);
        var jumpInput       = InputManager.GetButtonDown("Jump");

        var moveDirection   = Vector3.zero;
        var cameraTransform = CacheGameplayCameraControls != null ? CacheGameplayCameraControls.targetCamera.transform : Camera.main.transform;

        if (cameraTransform != null)
        {
            moveDirection += cameraTransform.forward * verticalInput;
            moveDirection += cameraTransform.right * horizontalInput;
        }
        moveDirection.y = 0;
        moveDirection   = moveDirection.normalized;

        if (moveDirection.magnitude > 0.1f && CacheUISceneGameplay != null && CacheUISceneGameplay.uiNpcDialog != null)
        {
            CacheUISceneGameplay.uiNpcDialog.Hide();
        }

        if (queueUsingSkill.HasValue)
        {
            destination = null;
            CharacterEntity.StopMove();
            var queueUsingSkillValue = queueUsingSkill.Value;
            var characterSkill       = CharacterEntity.Skills[queueUsingSkillValue.skillIndex];
            var skill = characterSkill.GetSkill();
            if (skill != null)
            {
                if (skill.IsAttack())
                {
                    BaseCharacterEntity targetEntity;
                    if (wasdLockAttackTarget && !CharacterEntity.TryGetTargetEntity(out targetEntity))
                    {
                        var nearestTarget = FindNearestAliveCharacter <MonsterCharacterEntity>(CharacterEntity.GetSkillAttackDistance(skill) + lockAttackTargetDistance);
                        if (nearestTarget != null)
                        {
                            CharacterEntity.SetTargetEntity(nearestTarget);
                        }
                        else
                        {
                            RequestUsePendingSkill();
                        }
                    }
                    else if (!wasdLockAttackTarget)
                    {
                        RequestUsePendingSkill();
                    }
                }
                else
                {
                    RequestUsePendingSkill();
                }
            }
            else
            {
                queueUsingSkill = null;
            }
        }
        else if (InputManager.GetButton("Attack"))
        {
            destination = null;
            CharacterEntity.StopMove();
            BaseCharacterEntity targetEntity;
            if (wasdLockAttackTarget && !CharacterEntity.TryGetTargetEntity(out targetEntity))
            {
                var nearestTarget = FindNearestAliveCharacter <MonsterCharacterEntity>(CharacterEntity.GetAttackDistance() + lockAttackTargetDistance);
                if (nearestTarget != null)
                {
                    CharacterEntity.SetTargetEntity(nearestTarget);
                }
                else
                {
                    RequestAttack();
                }
            }
            else if (!wasdLockAttackTarget)
            {
                RequestAttack();
            }
        }
        else
        {
            if (moveDirection.magnitude > 0)
            {
                if (CharacterEntity.HasNavPaths)
                {
                    CharacterEntity.StopMove();
                }
                destination = null;
                CharacterEntity.SetTargetEntity(null);
            }
            CharacterEntity.KeyMovement(moveDirection, jumpInput);
        }
    }