private void NormalTorch()
    {
        // Transition to Area
        if (Input.GetKey(KeyCode.E) && (!playerController.IsJumping()))
        {
            state = TorchState.Area;
            AreaTorch();
            return;
        }

        // Transition to Cone
        KeyCode input = InputUtils.CheckForMultipleInputs(KeyCode.DownArrow, KeyCode.LeftArrow, KeyCode.RightArrow);

        if (input != KeyCode.None)
        {
            spotLight.enabled  = true;
            pointLight.enabled = false;
            state = TorchState.Cone;
            ConeTorch();
            return;
        }

        if (rendererComp.flipX)
        {
            pointLight.gameObject.transform.localPosition = new Vector3(-INIT_TORCH_POS.x, INIT_TORCH_POS.y, INIT_TORCH_POS.z);
        }
        else
        {
            pointLight.gameObject.transform.localPosition = INIT_TORCH_POS;
        }

        // Check whether the player can recharge.
        bool nextToCrystal = false;

        foreach (Transform crystalPos in crystalPositions)
        {
            // If close enough to a crystal listen for recharging inputs.
            if ((crystalPos.position - transform.position).magnitude < 1f)
            {
                nextToCrystal = true;
                if (Input.GetKey(KeyCode.R))
                {
                    Recharge();
                    if (!particles.isPlaying)
                    {
                        particles.Play();
                    }
                }
            }
        }

        if (particles.isPlaying && (!Input.GetKey(KeyCode.R) || !nextToCrystal))
        {
            particles.Stop();
        }

        UpdateLight();

        energyRemaining = energyRemaining - Time.deltaTime;
    }
    private void AreaTorch()
    {
        // Transition to cone.
        KeyCode input = InputUtils.CheckForMultipleInputs(KeyCode.DownArrow, KeyCode.LeftArrow, KeyCode.RightArrow);

        if (input != KeyCode.None)
        {
            spotLight.enabled  = true;
            pointLight.enabled = false;
            state = TorchState.Cone;
            ConeTorch();
            return;
        }

        if (!Input.GetKey(KeyCode.E))
        {
            animator.SetBool(AnimationConstants.PLAYER_AREA_ATTACK, false);
            state = TorchState.Normal;
            NormalTorch();
            return;
        }

        if (!animator.GetBool(AnimationConstants.PLAYER_AREA_ATTACK))
        {
            animator.SetBool(AnimationConstants.PLAYER_AREA_ATTACK, true);
            pointLight.transform.localPosition = AREA_ATTACK_TORCH_POS;
            pointLight.range = AREA_ATTACK_TORCH_STRENGTH;
        }

        Collider2D[] hits = Physics2D.OverlapCircleAll(pointLight.transform.position, AREA_ATTACK_TORCH_RANGE);
        foreach (Collider2D hit in hits)
        {
            if (hit.gameObject.tag == Tags.ENEMY_TAG)
            {
                hit.gameObject.SendMessage("HitByLight", (Vector2)pointLight.transform.position, SendMessageOptions.DontRequireReceiver);
            }
        }

        energyRemaining -= (AREA_ATTACK_LIGHT_USAGE * Time.deltaTime);
    }
    private void ConeTorch()
    {
        KeyCode input = InputUtils.CheckForMultipleInputs(KeyCode.DownArrow, KeyCode.LeftArrow, KeyCode.RightArrow);

        if (input != KeyCode.None)
        {
            if (!spotLight.enabled)
            {
                spotLight.enabled = true;
            }

            ConeDirection direction = ConeDirection.UP;
            switch (input)
            {
            case KeyCode.RightArrow:
                rendererComp.flipX = false;
                spotLight.transform.eulerAngles   = new Vector3(0f, 90f, 0f);
                spotLight.transform.localPosition = SPOTLIGHT_INIT_POS;
                animator.SetBool(AnimationConstants.PLAYER_CONE_ATTACK, true);
                animator.SetBool(AnimationConstants.PLAYER_AREA_ATTACK, false);
                animator.SetBool("DownCone", false);
                direction = ConeDirection.RIGHT;
                break;

            case KeyCode.LeftArrow:
                rendererComp.flipX = true;
                spotLight.transform.eulerAngles   = new Vector3(180f, 90f, 0f);
                spotLight.transform.localPosition = new Vector3(-SPOTLIGHT_INIT_POS.x, SPOTLIGHT_INIT_POS.y, SPOTLIGHT_INIT_POS.z);
                animator.SetBool(AnimationConstants.PLAYER_CONE_ATTACK, true);
                animator.SetBool(AnimationConstants.PLAYER_AREA_ATTACK, false);
                animator.SetBool("DownCone", false);
                direction = ConeDirection.LEFT;
                break;

            /*
             * case KeyCode.UpArrow:
             *  spotLight.transform.eulerAngles = new Vector3(-90f, 90f, 0f);
             *  if(rendererComp.flipX)
             *  {
             *      spotLight.transform.localPosition = new Vector3(-SPOTLIGHT_UP_POS.x, SPOTLIGHT_UP_POS.y, SPOTLIGHT_UP_POS.z);
             *  }
             *  else
             *  {
             *      spotLight.transform.localPosition = SPOTLIGHT_UP_POS;
             *  }
             *  animator.SetBool(AnimationConstants.PLAYER_CONE_ATTACK, false);
             *  animator.SetBool(AnimationConstants.PLAYER_AREA_ATTACK, true);
             *  animator.SetBool("DownCone", false);
             *  direction = ConeDirection.UP;
             *  break;
             */

            case KeyCode.DownArrow:
                spotLight.transform.eulerAngles = new Vector3(90f, 90f, 0f);
                if (rendererComp.flipX)
                {
                    spotLight.transform.localPosition = new Vector3(-SPOTLIGHT_DOWN_POS.x, SPOTLIGHT_DOWN_POS.y, SPOTLIGHT_DOWN_POS.z);
                }
                else
                {
                    spotLight.transform.localPosition = SPOTLIGHT_DOWN_POS;
                }
                animator.SetBool(AnimationConstants.PLAYER_CONE_ATTACK, false);
                animator.SetBool(AnimationConstants.PLAYER_AREA_ATTACK, false);
                animator.SetBool("DownCone", true);
                direction = ConeDirection.DOWN;
                break;
            }

            int   numberOfRays        = 30;
            float rayAngle            = spotLight.spotAngle;
            float distanceBetweenRays = rayAngle / numberOfRays;
            float angleHalved         = rayAngle / 2;
            for (float angle = -angleHalved; angle < angleHalved; angle += distanceBetweenRays)
            {
                float worldAngle = angle;
                switch (direction)
                {
                case ConeDirection.RIGHT:
                    worldAngle = angle;
                    break;

                case ConeDirection.LEFT:
                    worldAngle = 180f + angle;
                    break;

                case ConeDirection.UP:
                    worldAngle = -90f + angle;
                    break;

                case ConeDirection.DOWN:
                    worldAngle = 90f + angle;
                    break;
                }

                Vector2        rayDirection = new Vector2(Mathf.Cos(Mathf.Deg2Rad * worldAngle), Mathf.Sin(Mathf.Deg2Rad * worldAngle));
                RaycastHit2D[] hits         = Physics2D.RaycastAll(spotLight.transform.position, rayDirection, CONE_ATTACK_TORCH_RANGE);
                foreach (RaycastHit2D hit in hits)
                {
                    if ((hit.collider != null) && (hit.collider.gameObject.tag == Tags.ENEMY_TAG))
                    {
                        hit.collider.gameObject.SendMessage("HitByLight", (Vector2)spotLight.transform.position, SendMessageOptions.DontRequireReceiver);
                    }
                }
            }
            energyRemaining -= (CONE_ATTACK_LIGHT_USAGE * Time.deltaTime);
        }
        else
        {
            spotLight.enabled  = false;
            pointLight.enabled = true;
            animator.SetBool(AnimationConstants.PLAYER_CONE_ATTACK, false);
            animator.SetBool(AnimationConstants.PLAYER_AREA_ATTACK, false);
            animator.SetBool("DownCone", false);
            state = TorchState.Normal;
            NormalTorch();
            return;
        }
    }