private Vector3 GetVectorFromDirection(HangInfo.Direction direction)
    {
        switch (direction)
        {
        case HangInfo.Direction.Left:
            return(-transform.right);

        case HangInfo.Direction.Right:
            return(transform.right);

        case HangInfo.Direction.None:
            Debug.LogWarning("Given direction is None... returning zero vector");
            return(Vector3.zero);

        default:
            throw new Exception("Dude something wrong");
        }
    }
 private static bool DirectionIsSame(HangInfo.Direction first, HangInfo.Direction second)
 {
     return(first == second);
 }
 private static bool DirectionIsOpposite(HangInfo.Direction first, HangInfo.Direction second)
 {
     // TODO: Check the other directions (up, down)
     return(first == HangInfo.Direction.Left && second == HangInfo.Direction.Right ||
            first == HangInfo.Direction.Right && second == HangInfo.Direction.Left);
 }
    private void Shimmy(HangInfo.Direction direction)
    {
        if (direction == HangInfo.Direction.None)
        {
            return;
        }
        Debug.Log("Shimmy " + direction + " entered");
        Debug.Log("Current state is " + _hang.state);
        switch (_hang.state)
        {
        case HangInfo.HangState.Final:
        {
            // We obtain the next point depending on the direction intended to shimmy to
            _hang.nextPoint = _hang.currentPoint.GetNextPoint(GetVectorFromDirection(direction));
            // If there is no point in that direction, simply return, nothing to do here
            if (_hang.nextPoint == null)
            {
                Debug.Log("No point on the " + direction);
                return;
            }
            // We keep the current shimmy direction in memory
            _hang.currentDirection = direction;
            // We set the new state
            _hang.state = HangInfo.HangState.Midpoint;
            // TODO: Handle IKs for other directions
            switch (_hang.currentDirection)
            {
            case HangInfo.Direction.Right:
                SetRightHand(_hang.nextPoint);
                SetLeftHand(_hang.currentPoint);
                break;

            case HangInfo.Direction.Left:
                SetRightHand(_hang.currentPoint);
                SetLeftHand(_hang.nextPoint);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            // Set the transform position of the character
            transform.position = Vector3.Lerp(
                _hang.currentPoint.characterRoot.transform.position,
                _hang.nextPoint.characterRoot.transform.position,
                0.5f);
            _controller.isShimmyLeft  = false;
            _controller.isShimmyRight = false;
            break;
        }

        case HangInfo.HangState.Midpoint:
        {
            // If we are trying to continue the movement
            if (DirectionIsSame(_hang.currentDirection, direction))
            {
                Debug.Log("Direction is same: " + direction);
                // Then the current point will become the next point;
                _hang.currentPoint = _hang.nextPoint;
            }
            // If we are trying to cancel the movement
            else if (DirectionIsOpposite(_hang.currentDirection, direction))
            {
                Debug.Log("Direction is opposite: " + direction);
            }

            // And we will no longer have a "next" point
            _hang.nextPoint = null;
            // We tell the controller how we are actually hanging to that point
            _controller.hangType = _hang.currentPoint.hangType;
// We set the hand IKs
            SetRightHand(_hang.currentPoint);
            SetLeftHand(_hang.currentPoint);
            // Set the transform position of the character
            transform.position = _hang.currentPoint.characterRoot.transform.position;
            _hang.state        = HangInfo.HangState.Final;
            switch (direction)
            {
            case HangInfo.Direction.Left:
                _controller.isShimmyLeft = true;
                break;

            case HangInfo.Direction.Right:
                _controller.isShimmyRight = true;
                break;
            }

            break;
        }

        default:
            throw new ArgumentOutOfRangeException();
        }
    }