public void UpdatePosition()
        {
            var rotation       = Quaternion.Euler(Vertical, Horizontal, 0);
            var transformPivot = _motorRotation * _pivot + _motorPosition;
            var cameraPosition = transformPivot + rotation * _offset;
            var cameraTarget   = _motorPosition + _pivot + rotation * Vector3.forward * 100;

            if (Target.Gun != null && Target.IsZooming && Target.Gun.Scope != null)
            {
                Target.InputLayer(ScopeLayer);

                if (!_wasScoped)
                {
                    _scopeHeight = Target.TargetHeight;

                    var origin = Target.transform.position + Vector3.up * _scopeHeight * 0.8f;

                    var target = Util.GetClosestHit(cameraPosition, cameraTarget, 0, null);

                    if (!Target.CanPeekLeftCorner && !Target.CanPeekRightCorner)
                    {
                        _scopeOffset = Quaternion.FromToRotation((cameraTarget - origin).normalized, (target - origin).normalized);
                    }
                    else
                    {
                        _scopeOffset = Quaternion.identity;
                    }

                    _wasScoped = true;
                }

                transform.position = Target.transform.position + Vector3.up * _scopeHeight * 0.8f;
                Target.FireFrom(transform.position);

                transform.LookAt(_scopeOffset * (cameraTarget - transform.position) + transform.position);

                _scopeHeight = Mathf.Lerp(_scopeHeight, Target.TargetHeight, Time.deltaTime * 6);
            }
            else
            {
                _wasScoped = false;

                var forward = (cameraTarget - cameraPosition).normalized;

                var colliderFixTarget = Vector3.zero;

                if (AvoidObstacles)
                {
                    colliderFixTarget = checkObstacles(cameraPosition, _motorPosition + Target.StandingHeight * Vector3.up, 0.1f);
                }

                _obstacleFix    = Vector3.Lerp(_obstacleFix, colliderFixTarget, Time.deltaTime * 30);
                cameraPosition += _obstacleFix;

                transform.position = cameraPosition;
                transform.LookAt(cameraTarget);

                if (Target.IsFiringFromCamera)
                {
                    Target.FireFrom(transform.position);
                }
                else
                {
                    Target.SetDefaultFireOrigin();
                }
            }
        }
        private void Update()
        {
            if (Target == null)
            {
                return;
            }

            var controller = getCurrentController();

            if (Cursor.lockState == CursorLockMode.Locked || RotateWhenUnlocked)
            {
                Horizontal = Mathf.LerpAngle(Horizontal, Horizontal + Input.GetAxis("Mouse X") * HorizontalRotateSpeed * Time.timeScale, 1.0f);
                Vertical   = Mathf.LerpAngle(Vertical, Vertical - Input.GetAxis("Mouse Y") * VerticalRotateSpeed * Time.timeScale, 1.0f);
            }

            Vertical = Mathf.Clamp(Vertical, -45, 70);

            var newPosition = Target.GetPivotPosition();
            var newRotation = Target.GetPivotRotation();

            if (Target.IsInCornerAimState)
            {
                _motorPivotSpeed = 0;
            }
            else
            {
                _motorPivotSpeed = Mathf.Lerp(_motorPivotSpeed, 1, Time.deltaTime * 5);
            }

            if (Target.IsInCover != _wasInCover)
            {
                _motorPivotSpeed = 0;
            }

            _motorPosition = Vector3.Lerp(_motorPosition, newPosition, Mathf.Lerp(Time.deltaTime * 5, 1, _motorPivotSpeed));
            _motorRotation = Quaternion.Slerp(_motorRotation, newRotation, Mathf.Lerp(Time.deltaTime * 3, 1, _motorPivotSpeed));

            var rotation       = Quaternion.Euler(Vertical, Horizontal, 0);
            var transformPivot = _motorRotation * _pivot + _motorPosition;
            var cameraPosition = transformPivot + rotation * _offset;
            var cameraTarget   = _motorPosition + _pivot + rotation * Vector3.forward * 100;

            var forward = (cameraTarget - cameraPosition).normalized;

            var colliderFixTarget = Vector3.zero;

            if (AvoidObstacles)
            {
                colliderFixTarget = checkObstacles(cameraPosition, _motorPosition + Target.StandingHeight * Vector3.up, 0.1f);
            }

            _obstacleFix    = Vector3.Lerp(_obstacleFix, colliderFixTarget, Time.deltaTime * 30);
            cameraPosition += _obstacleFix;

            transform.position = cameraPosition;
            transform.LookAt(cameraTarget);

            {
                var plane = new Plane(_motorPosition, _motorPosition + transform.up, _motorPosition + transform.right);
                var ray   = new Ray(cameraPosition, (cameraTarget - cameraPosition).normalized);

                float   enter;
                Vector3 hit;

                if (plane.Raycast(ray, out enter))
                {
                    hit = cameraPosition + ray.direction * enter;
                }
                else
                {
                    hit  = getClosestHit(cameraPosition, cameraTarget, 0.1f);
                    hit -= transform.forward * 0.2f;
                }

                SendMessage("OnFadeTarget", new FadeTarget(Target.gameObject, hit), SendMessageOptions.DontRequireReceiver);
            }

            var lookPosition = transform.position + transform.forward * 1000;

            if (controller != null)
            {
                controller.LookTargetInput      = lookPosition;
                controller.HorizontalAngleInput = Util.AngleOfVector(transform.forward);
                controller.VerticalAngleInput   = Mathf.Asin(transform.forward.y) * 180f / Mathf.PI;
            }
            else
            {
                Target.SetLookTarget(lookPosition);
            }

            var closestHit = getClosestHit(transform.position, lookPosition, Vector3.Distance(transform.position, Target.Top));

            if (Target.TurnSettings.IsAimingPrecisely)
            {
                closestHit += transform.forward;
            }

            _lastTargetDistance = Vector3.Distance(transform.position, closestHit);

            if (controller != null)
            {
                controller.FireTargetInput = closestHit;
            }
            else
            {
                Target.SetFireTarget(closestHit);
            }

            if (Target.IsFiringFromCamera)
            {
                Target.FireFrom(transform.position);
            }
            else
            {
                Target.SetDefaultFireOrigin();
            }

            float       alphaTarget = 1;
            CameraState state;

            if (Target.HasGrenadeInHand)
            {
                alphaTarget = 0;
            }

            if (!Target.IsAlive)
            {
                state       = States.Dead;
                alphaTarget = 0;
            }
            else if (controller != null && controller.IsZooming)
            {
                if (Target.IsCornerAiming)
                {
                    if (Target.IsInTallCover)
                    {
                        state = Target.IsStandingLeftInCover ? States.LeftTallCornerZoom : States.RightTallCornerZoom;
                    }
                    else
                    {
                        state = Target.IsStandingLeftInCover ? States.LeftLowCornerZoom : States.RightLowCornerZoom;
                    }
                }
                else if (Target.IsInCover)
                {
                    if (!Target.IsInTallCover && Target.IsAimingBackFromCover)
                    {
                        state = States.LowCoverBackZoom;
                    }
                    else
                    {
                        state = States.LowCoverZoom;
                    }
                }
                else if (Target.IsCrouching)
                {
                    state = States.CrouchZoom;
                }
                else
                {
                    state = States.Zoom;
                }
            }
            else if (Target.IsClimbing)
            {
                state = States.Climb;
            }
            else if (Target.CanPeekLeftCorner && Target.IsStandingLeftInCover)
            {
                state = States.LeftCorner;
            }
            else if (Target.CanPeekRightCorner && !Target.IsStandingLeftInCover)
            {
                state = States.RightCorner;
            }
            else if (Target.IsInCover)
            {
                if (Target.IsInTallCover)
                {
                    if (Target.IsAimingBackFromCover)
                    {
                        state = States.TallCoverBack;
                    }
                    else
                    {
                        if (!Target.CanPeekLeftCorner &&
                            !Target.CanPeekRightCorner &&
                            !Target.CanWallAim)
                        {
                            alphaTarget = 0;
                        }

                        if (Target.IsStandingLeftInCover)
                        {
                            state = States.TallCoverLeft;
                        }
                        else
                        {
                            state = States.TallCoverRight;
                        }
                    }
                }
                else if (Target.HasGrenadeInHand)
                {
                    state = States.LowCoverGrenade;
                }
                else
                {
                    state = States.LowCover;
                }
            }
            else if (Target.IsCrouching)
            {
                state = States.Crouch;
            }
            else if (Target.WouldAim)
            {
                state = States.Aim;
            }
            else
            {
                alphaTarget = 0;
                state       = States.Default;
            }

            _camera.fieldOfView = Mathf.Lerp(_camera.fieldOfView, state.FOV, Time.deltaTime * 6);

            _crosshairAlpha = Mathf.Lerp(_crosshairAlpha, alphaTarget, Time.deltaTime * 6);

            _pivot       = Vector3.Lerp(_pivot, state.Pivot, Time.deltaTime * 6);
            _offset      = Vector3.Lerp(_offset, state.Offset, Time.deltaTime * 6);
            _orientation = Vector3.Lerp(_orientation, state.Orientation, Time.deltaTime * 6);

            _wasInCover = Target.IsInCover;
        }