/// <summary>
        /// Performs a camera focus operation on the currently selected game objects. The
        /// method uses the current focs settings to perform the focus operation.
        /// </summary>
        /// <remarks>
        /// The method has no effect if there are no objects currently selected.
        /// </remarks>
        public void FocusOnSelection()
        {
            // Focussing on the default object is not selected in constant and smooth focus mode
            if (EditorObjectSelection.Instance.NumberOfSelectedObjects == 0 &&
                (_focusSettings.FocusMode == EditorCameraFocusMode.ConstantSpeed || _focusSettings.FocusMode == EditorCameraFocusMode.Smooth)
                )
            {
                return;
            }

            // Focus the camera based on the chosen focus method
            if (_focusSettings.FocusMode == EditorCameraFocusMode.Instant)
            {
                //Select the default focus object
                bool selectedDefaultFocusObject = false;
                if (EditorObjectSelection.Instance.NumberOfSelectedObjects == 0)
                {
                    selectedDefaultFocusObject = EditorObjectSelection.Instance.AddObjectAndItsChildrenToSelection(_focusSettings.DefaultFocusObject);
                }

                //EditorObjectSelection.Instance.AddObjectToSelection(_focusSettings.DefaultFocusObject, false);
                // Get the focus info
                EditorCameraFocusOperationInfo focusOpInfo = EditorCameraFocus.GetFocusOperationInfo(Camera, _focusSettings);

                // Note: We will also adjust the ortho size to make sure things are all well when
                //       switching from a perspective to orthographic camera.
                Camera.orthographicSize   = focusOpInfo.OrthoCameraHalfVerticalSize;
                Camera.transform.position = focusOpInfo.CameraDestinationPosition;

                // The camera was focused
                _wasFocused     = true;
                _lastFocusPoint = focusOpInfo.FocusPoint;
                CalculateOrbitOffsetAlongLook(focusOpInfo);

                // Deselect the default focus object
                if (selectedDefaultFocusObject)
                {
                    /// Undo select all
                    EditorUndoRedoSystem.Instance.OnUndo();
                }
            }
            else
            if (_focusSettings.FocusMode == EditorCameraFocusMode.ConstantSpeed)
            {
                StopCoroutine("StartConstantFocusOnSelection");
                StopCoroutine("StartSmoothZoom");
                StopCoroutine("StartSmoothPan");

                StartCoroutine("StartConstantFocusOnSelection");
            }
            else
            if (_focusSettings.FocusMode == EditorCameraFocusMode.Smooth)
            {
                StopCoroutine("StartSmoothFocusOnSelection");
                StopCoroutine("StartSmoothZoom");
                StopCoroutine("StartSmoothPan");

                StartCoroutine("StartSmoothFocusOnSelection");
            }
        }
        /// <summary>
        /// Starts a smooth focus operation on the current object selection.
        /// </summary>
        private IEnumerator StartSmoothFocusOnSelection()
        {
            // Store needed data
            EditorCameraFocusOperationInfo focusOpInfo = EditorCameraFocus.GetFocusOperationInfo(Camera, _focusSettings);

            _lastFocusPoint = focusOpInfo.FocusPoint;
            Vector3   cameraDestinationPoint = focusOpInfo.CameraDestinationPosition;
            Transform cameraTransform        = Camera.transform;

            // If the distance to travel is small enough, we can exit
            if ((cameraDestinationPoint - cameraTransform.position).magnitude < 1e-4f)
            {
                yield break;
            }

            // We will need this to modify the position using 'Vector3.SmoothDamp'
            Vector3 velocity = Vector3.zero;

            // We will need this to modify the camera ortho size using 'Mathf.SmoothDamp'.
            float orthoSizeVelocity = 0.0f;

            // The first iteration of the 'while' loop will perform the first focus step. We will
            // set this to true here just in case the focus operation is cancelled by another camera
            // operation. This will allow the user to orbit the camera even if it wasn't focused 100%.
            _wasFocused = true;

            while (true)
            {
                // Calculate the new position
                cameraTransform.position = Vector3.SmoothDamp(cameraTransform.position, cameraDestinationPoint, ref velocity, _focusSettings.SmoothFocusTime);

                // Calculate the new camera ortho size
                SetOrthoSize(Mathf.SmoothDamp(Camera.orthographicSize, focusOpInfo.OrthoCameraHalfVerticalSize, ref orthoSizeVelocity, _focusSettings.SmoothFocusTime));

                // Recalculate the orbit focus to ensure proper orbit if the focus operation is not completed 100%.
                CalculateOrbitOffsetAlongLook(focusOpInfo);

                // If the position is close enough to the target position and the camera ortho size
                // is close enough to the target size, we can exit the loop.
                if ((cameraTransform.position - cameraDestinationPoint).magnitude < 1e-3f &&
                    Mathf.Abs(Camera.orthographicSize - focusOpInfo.OrthoCameraHalfVerticalSize) < 1e-3f)
                {
                    // Clamp to make sure we got the correct values and then exit the loop
                    cameraTransform.position = cameraDestinationPoint;
                    Camera.orthographicSize  = focusOpInfo.OrthoCameraHalfVerticalSize;

                    break;
                }

                yield return(null);
            }
        }
        /// <summary>
        /// Performs a camera focus operation on the currently selected game objects. The
        /// method uses the current focs settings to perform the focus operation.
        /// </summary>
        /// <remarks>
        /// The method has no effect if there are no objects currently selected.
        /// </remarks>
        public void FocusOnSelection()
        {
            // No objects selected?
            if (EditorObjectSelection.Instance.NumberOfSelectedObjects == 0)
            {
                return;
            }

            // Focus the camera based on the chosen focus method
            if (_focusSettings.FocusMode == EditorCameraFocusMode.Instant)
            {
                // Get the focus info
                EditorCameraFocusOperationInfo focusOpInfo = EditorCameraFocus.GetFocusOperationInfo(Camera, _focusSettings);

                // Note: We will also adjust the ortho size to make sure things are all well when
                //       switching from a perspective to orthographic camera.
                Camera.orthographicSize   = focusOpInfo.OrthoCameraHalfVerticalSize;
                Camera.transform.position = focusOpInfo.CameraDestinationPosition;

                // The camera was focused
                _wasFocused     = true;
                _lastFocusPoint = focusOpInfo.FocusPoint;
                CalculateOrbitOffsetAlongLook(focusOpInfo);
            }
            else
            if (_focusSettings.FocusMode == EditorCameraFocusMode.ConstantSpeed)
            {
                StopCoroutine("StartConstantFocusOnSelection");
                StopCoroutine("StartSmoothZoom");
                StopCoroutine("StartSmoothPan");

                StartCoroutine("StartConstantFocusOnSelection");
            }
            else
            if (_focusSettings.FocusMode == EditorCameraFocusMode.Smooth)
            {
                StopCoroutine("StartSmoothFocusOnSelection");
                StopCoroutine("StartSmoothZoom");
                StopCoroutine("StartSmoothPan");

                StartCoroutine("StartSmoothFocusOnSelection");
            }
        }
        /// <summary>
        /// Starts a constant focus operation on the current object selection.
        /// </summary>
        private IEnumerator StartConstantFocusOnSelection()
        {
            // Store needed data
            EditorCameraFocusOperationInfo focusOpInfo = EditorCameraFocus.GetFocusOperationInfo(Camera, _focusSettings);

            _lastFocusPoint = focusOpInfo.FocusPoint;
            Vector3   cameraDestinationPoint = focusOpInfo.CameraDestinationPosition;
            float     cameraSpeed            = _focusSettings.ConstantFocusSpeed;
            Transform cameraTransform        = Camera.transform;

            // Calculate the vector which is used to move the camera from its current position to the destination position.
            // We will normalize this vector so that we can move along it with the required speed.
            Vector3 fromCamPosToDestination = cameraDestinationPoint - cameraTransform.position;
            float   distanceToTravel        = fromCamPosToDestination.magnitude; // Needed later inside the 'while' loop

            if (distanceToTravel < 1e-4f)
            {
                yield break;                                                 // No focus necessary?
            }
            fromCamPosToDestination.Normalize();

            // We will need this to know how much we travelled
            Vector3 initialCameraPosition = cameraTransform.position;

            // We will need this to adjust the ortho camera size
            float initialCameraOrthoSize = Camera.orthographicSize;

            // The first iteration of the 'while' loop will perform the first focus step. We will
            // set this to true here just in case the focus operation is cancelled by another camera
            // operation. This will allow the user to orbit the camera even if it wasn't focused 100%.
            _wasFocused = true;

            while (true)
            {
                // Move the camera along the direction vector with the desired speed
                cameraTransform.position += (fromCamPosToDestination * cameraSpeed * Time.deltaTime);

                // Calculate the new camera ortho size. This is done by lerping between the initial
                // ortho size and the target size. The interpolation factor is the ratio between how
                // much we travelled so far and the total distance that we have to travel.
                float distanceTraveledSoFar = (cameraTransform.position - initialCameraPosition).magnitude;
                SetOrthoSize(Mathf.Lerp(initialCameraOrthoSize, focusOpInfo.OrthoCameraHalfVerticalSize, distanceTraveledSoFar / distanceToTravel));

                // Recalculate the orbit focus to ensure proper orbit if the focus operation is not completed 100%.
                CalculateOrbitOffsetAlongLook(focusOpInfo);

                // Check if the camera has reached the destination position or if it went past it. It is very
                // probable that most of the times, the camera will move further away than the target position.
                // When that happens, we will clamp the camera position and exit the coroutine. In order to detect
                // this situation, we will perform a dot product between the camera move direction vector and
                // the vector which unites the current camera position with the target position. When this dot
                // product is < 0, it means that the camera has moved too far away and we will clamp its position
                // and exit. This could also probably be done using a variable which holds the accumulated travel
                // distance. When this distance becomes >= than the original length of 'fromCamPosToDestination',
                // we can exit.
                if (Vector3.Dot(fromCamPosToDestination, cameraDestinationPoint - cameraTransform.position) <= 0.0f &&
                    Mathf.Abs(Camera.orthographicSize - focusOpInfo.OrthoCameraHalfVerticalSize) < 1e-3f)
                {
                    cameraTransform.position = cameraDestinationPoint;
                    break;
                }

                yield return(null);
            }
        }
        /// <summary>
        /// Rotates the camera based on user input.
        /// </summary>
        private void RotateCameraBasedOnUserInput()
        {
            // If no mouse movemenet was performed, we don't need to continue
            if (!_mouse.WasMouseMovedSinceLastFrame)
            {
                return;
            }

            //added by me
            if (WereAnyUIElementsHovered())
            {
                return;
            }
            bool orbit         = _cameraOrbitShortcut.IsActive() || toolBarController.isOrbiting;
            bool orbitSelected = toolBarController.isOrbitingSelected;
            //
            //bool orbit = _cameraOrbitShortcut.IsActive();
            bool lookAround = !orbit && _cameraLookAroundShortcut.IsActive();

            //if (orbit || lookAround)
            //added by me
            if (orbit || lookAround || orbitSelected)
            //
            {
                // Make sure all coroutines are stopped to avoid any conflicts
                StopAllCoroutines();

                // Calculate the amount of rotation which must be applied
                float rotationSpeedTimesDeltaTime = _rotationSpeedInDegrees * Time.deltaTime;

                // Rotate based on the type of rotation we are dealing with.
                // Note: Even if the rotation mode is set to orbit, we will still perform a 'LookAround' rotation
                //       if the camera hasn't been focused.
                //added by me
                if (orbitSelected)  //围绕选中物体旋转
                {
                    Transform cameraTransform = Camera.transform;

                    EditorCameraOrbit.OrbitCameraBaseOnSelected(Camera,
                                                                -_mouse.CursorOffsetSinceLastFrame.y * rotationSpeedTimesDeltaTime,
                                                                _mouse.CursorOffsetSinceLastFrame.x * rotationSpeedTimesDeltaTime, EditorCameraFocus.GetFocusOperationInfo(Camera, _focusSettings).FocusPoint);
                }
                else
                //
                if (lookAround || !_wasFocused)
                {
                    EditorCameraRotation.RotateCamera(Camera,
                                                      -_mouse.CursorOffsetSinceLastFrame.y * rotationSpeedTimesDeltaTime,
                                                      _mouse.CursorOffsetSinceLastFrame.x * rotationSpeedTimesDeltaTime);
                }
                else
                if (_wasFocused && orbit)
                {
                    // Calculate the orbit point. This is done by moving from the camera position along the camera
                    // look vector by a distance equal to '_orbitOffsetAlongLook'.
                    Transform cameraTransform = Camera.transform;
                    Vector3   orbitPoint      = cameraTransform.position + cameraTransform.forward * _orbitOffsetAlongLook;

                    EditorCameraOrbit.OrbitCamera(Camera,
                                                  -_mouse.CursorOffsetSinceLastFrame.y * rotationSpeedTimesDeltaTime,
                                                  _mouse.CursorOffsetSinceLastFrame.x * rotationSpeedTimesDeltaTime, orbitPoint);
                }
            }
        }