void DrawSceneTools()
        {
            var framingTransposer = Target;

            if (framingTransposer == null || !framingTransposer.IsValid)
            {
                return;
            }

            if (CinemachineSceneToolUtility.IsToolActive(typeof(TrackedObjectOffsetTool)))
            {
                CinemachineSceneToolHelpers.TrackedObjectOffsetTool(framingTransposer,
                                                                    new SerializedObject(framingTransposer).FindProperty(() => framingTransposer.m_TrackedObjectOffset));
            }
            else if (CinemachineSceneToolUtility.IsToolActive(typeof(FollowOffsetTool)))
            {
                var originalColor = Handles.color;
                var camPos        = framingTransposer.VcamState.RawPosition;
                var targetForward = framingTransposer.VirtualCamera.State.FinalOrientation * Vector3.forward;
                EditorGUI.BeginChangeCheck();
                Handles.color = CinemachineSceneToolHelpers.HelperLineDefaultColor;
                var cdHandleId        = GUIUtility.GetControlID(FocusType.Passive);
                var newHandlePosition = Handles.Slider(cdHandleId, camPos, targetForward,
                                                       CinemachineSceneToolHelpers.CubeHandleCapSize(camPos), Handles.CubeHandleCap, 0.5f);
                if (EditorGUI.EndChangeCheck())
                {
                    // Modify via SerializedProperty for OnValidate to get called automatically, and scene repainting too
                    var so   = new SerializedObject(framingTransposer);
                    var prop = so.FindProperty(() => framingTransposer.m_CameraDistance);
                    prop.floatValue -= CinemachineSceneToolHelpers.SliderHandleDelta(newHandlePosition, camPos, targetForward);
                    so.ApplyModifiedProperties();
                }

                var cameraDistanceHandleIsDragged       = GUIUtility.hotControl == cdHandleId;
                var cameraDistanceHandleIsUsedOrHovered = cameraDistanceHandleIsDragged ||
                                                          HandleUtility.nearestControl == cdHandleId;
                if (cameraDistanceHandleIsUsedOrHovered)
                {
                    CinemachineSceneToolHelpers.DrawLabel(camPos,
                                                          "Camera Distance (" + framingTransposer.m_CameraDistance.ToString("F1") + ")");
                }

                Handles.color = cameraDistanceHandleIsUsedOrHovered ?
                                Handles.selectedColor : CinemachineSceneToolHelpers.HelperLineDefaultColor;
                Handles.DrawLine(camPos,
                                 framingTransposer.FollowTarget.position + framingTransposer.m_TrackedObjectOffset);

                CinemachineSceneToolHelpers.SoloOnDrag(cameraDistanceHandleIsDragged, framingTransposer.VirtualCamera,
                                                       cdHandleId);

                Handles.color = originalColor;
            }
        }
예제 #2
0
        void DrawSceneTools()
        {
            var thirdPerson = Target;

            if (thirdPerson == null || !thirdPerson.IsValid)
            {
                return;
            }

            if (CinemachineSceneToolUtility.IsToolActive(typeof(FollowOffsetTool)))
            {
                var originalColor = Handles.color;

                thirdPerson.GetRigPositions(out var followTargetPosition, out var shoulderPosition,
                                            out var armPosition);
                var followTargetRotation = thirdPerson.FollowTargetRotation;
                var targetForward        = followTargetRotation * Vector3.forward;
                var heading = Cinemachine3rdPersonFollow.GetHeading(
                    followTargetRotation, thirdPerson.VirtualCamera.State.ReferenceUp);

                EditorGUI.BeginChangeCheck();
                // shoulder handle
#if UNITY_2022_2_OR_NEWER
                var sHandleIds          = Handles.PositionHandleIds.@default;
                var newShoulderPosition = Handles.PositionHandle(sHandleIds, shoulderPosition, heading);
                var sHandleMinId        = sHandleIds.x - 1;
                var sHandleMaxId        = sHandleIds.xyz + 1;
#else
                var sHandleMinId        = GUIUtility.GetControlID(FocusType.Passive);
                var newShoulderPosition = Handles.PositionHandle(shoulderPosition, heading);
                var sHandleMaxId        = GUIUtility.GetControlID(FocusType.Passive);
#endif

                Handles.color = Handles.preselectionColor;
                // arm handle
                var followUp       = followTargetRotation * Vector3.up;
                var aHandleId      = GUIUtility.GetControlID(FocusType.Passive);
                var newArmPosition = Handles.Slider(aHandleId, armPosition, followUp,
                                                    CinemachineSceneToolHelpers.CubeHandleCapSize(armPosition), Handles.CubeHandleCap, 0.5f);

                // cam distance handle
                var camDistance = thirdPerson.CameraDistance;
                var camPos      = armPosition - targetForward * camDistance;
                var cdHandleId  = GUIUtility.GetControlID(FocusType.Passive);
                var newCamPos   = Handles.Slider(cdHandleId, camPos, targetForward,
                                                 CinemachineSceneToolHelpers.CubeHandleCapSize(camPos), Handles.CubeHandleCap, 0.5f);
                if (EditorGUI.EndChangeCheck())
                {
                    // Modify via SerializedProperty for OnValidate to get called automatically, and scene repainting too
                    var so = new SerializedObject(thirdPerson);

                    var shoulderOffset = so.FindProperty(() => thirdPerson.ShoulderOffset);
                    shoulderOffset.vector3Value +=
                        CinemachineSceneToolHelpers.PositionHandleDelta(heading, newShoulderPosition, shoulderPosition);
                    var verticalArmLength = so.FindProperty(() => thirdPerson.VerticalArmLength);
                    verticalArmLength.floatValue +=
                        CinemachineSceneToolHelpers.SliderHandleDelta(newArmPosition, armPosition, followUp);
                    var cameraDistance = so.FindProperty(() => thirdPerson.CameraDistance);
                    cameraDistance.floatValue -=
                        CinemachineSceneToolHelpers.SliderHandleDelta(newCamPos, camPos, targetForward);

                    so.ApplyModifiedProperties();
                }

                var isDragged = IsHandleDragged(sHandleMinId, sHandleMaxId, shoulderPosition, "Shoulder Offset "
                                                + thirdPerson.ShoulderOffset.ToString("F1"), followTargetPosition, shoulderPosition);
                isDragged |= IsHandleDragged(aHandleId, aHandleId, armPosition, "Vertical Arm Length ("
                                             + thirdPerson.VerticalArmLength.ToString("F1") + ")", shoulderPosition, armPosition);
                isDragged |= IsHandleDragged(cdHandleId, cdHandleId, camPos, "Camera Distance ("
                                             + camDistance.ToString("F1") + ")", armPosition, camPos);

                CinemachineSceneToolHelpers.SoloOnDrag(isDragged, thirdPerson.VirtualCamera, sHandleMaxId);

                Handles.color = originalColor;
            }