protected void FollowTarget()
        {
            Rect  cameraRect      = Utilities2D.CameraBounds2D(_camera);
            float horizontalScale = 1.0f;
            float verticalScale   = 1.0f;

            Vector3 targetPos = GetTargetPosition();

            if (float.IsNaN(targetPos.x) || float.IsNaN(targetPos.y))
            {
                return;
            }

            if (_checkForBounds)
            {
                // left smooth edge
                if (targetPos.x < _transform.position.x &&
                    cameraRect.x > _bounds.x && cameraRect.x < _innerBounds.x)
                {
                    horizontalScale = 1.0f + (cameraRect.x - _innerBounds.x) / smoothEdge;
                }
                // right smooth edge
                else if (targetPos.x > _transform.position.x &&
                         cameraRect.xMax > _innerBounds.xMax && cameraRect.xMax < _bounds.xMax)
                {
                    horizontalScale = 1.0f - (cameraRect.xMax - _innerBounds.xMax) / smoothEdge;
                }
                // hard left edge
                else if (targetPos.x < _transform.position.x &&
                         cameraRect.x <= _bounds.x)
                {
                    horizontalScale = 0;
                }
                // hard right edge
                else if (targetPos.x > _transform.position.x &&
                         cameraRect.xMax >= _bounds.xMax)
                {
                    horizontalScale = 0;
                }

                // bottom edge
                if (targetPos.y < _transform.position.y &&
                    cameraRect.y > _bounds.y && cameraRect.y < _innerBounds.y)
                {
                    verticalScale = 1.0f + (cameraRect.y - _innerBounds.y) / smoothEdge;
                }
                // top edge
                else if (targetPos.y > _transform.position.y &&
                         cameraRect.yMax > _innerBounds.yMax && cameraRect.yMax < _bounds.yMax)
                {
                    verticalScale = 1.0f - (cameraRect.yMax - _innerBounds.yMax) / smoothEdge;
                }
                // hard bottom edge
                else if (targetPos.y < _transform.position.y &&
                         cameraRect.y <= _bounds.y)
                {
                    verticalScale = 0;
                }
                // hard top edge
                else if (targetPos.y > _transform.position.y &&
                         cameraRect.yMax >= _bounds.yMax)
                {
                    verticalScale = 0;
                }
            }

            float targetX = Mathf.Lerp(_transform.position.x, targetPos.x, horizontalFollowSpeed * Time.deltaTime * horizontalScale);

            if (direction == MoveDirection.Vertical)
            {
                targetX = _transform.position.x;
            }

            float targetY = Mathf.Lerp(_transform.position.y, targetPos.y, verticalFollowSpeed * Time.deltaTime * verticalScale);

            if (direction == MoveDirection.Horizontal)
            {
                targetY = _transform.position.y;
            }

            _transform.position = new Vector3(targetX, targetY, _transform.position.z);

            ApplyBounds();
        }