예제 #1
0
        public void OnEnable()
        {
            MethodInfo method = editor.GetType().GetMethod("OnEnable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            if (method != null)
            {
                method.Invoke(editor, null);
            }
        }
예제 #2
0
        private bool Init(UnityEngine.Object obj, EditorFeatures requirements)
        {
            editor = Editor.CreateEditor(obj);
            if (editor == null)
            {
                return(false);
            }
            if ((requirements & EditorFeatures.PreviewGUI) > EditorFeatures.None && !editor.HasPreviewGUI())
            {
                return(false);
            }
            Type       type   = editor.GetType();
            MethodInfo method = type.GetMethod("OnSceneDrag", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            if (method != null)
            {
                OnSceneDrag = (EditorWrapper.VoidDelegate)Delegate.CreateDelegate(typeof(EditorWrapper.VoidDelegate), editor, method);
            }
            else
            {
                if ((requirements & EditorFeatures.OnSceneDrag) > EditorFeatures.None)
                {
                    return(false);
                }
                OnSceneDrag = new EditorWrapper.VoidDelegate(DefaultOnSceneDrag);
            }
            return(true);
        }
예제 #3
0
        private bool Init(Object obj, EditorFeatures requirements)
        {
            MethodInfo onSceneDragMi;

            editor = Editor.CreateEditor(obj);
            if (editor == null)
            {
                return(false);
            }

            if ((int)(requirements & EditorFeatures.PreviewGUI) > 0 && !editor.HasPreviewGUI())
            {
                return(false);
            }

            System.Type t = editor.GetType();

            onSceneDragMi = t.GetMethod("OnSceneDrag", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            if (onSceneDragMi != null)
            {
                OnSceneDrag = (VoidDelegate)System.Delegate.CreateDelegate(typeof(VoidDelegate), editor, onSceneDragMi);
            }
            else if ((int)(requirements & EditorFeatures.OnSceneDrag) > 0)
            {
                return(false);
            }
            else
            {
                OnSceneDrag = DefaultOnSceneDrag;
            }

            return(true);
        }
        void UpdateRigEditor()
        {
            var selectedRig = GetSelectedRig(Target);
            CinemachineVirtualCamera rig = Target.GetRig(selectedRig);

            if (m_EditedRig != rig || m_rigEditor == null)
            {
                m_EditedRig           = rig;
                m_RigEditorOnSceneGUI = null;
                if (m_rigEditor != null)
                {
                    UnityEngine.Object.DestroyImmediate(m_rigEditor);
                    m_rigEditor = null;
                }
                if (rig != null)
                {
                    CreateCachedEditor(rig, null, ref m_rigEditor);
                    if (m_rigEditor != null)
                    {
                        m_RigEditorOnSceneGUI = m_rigEditor.GetType().GetMethod("OnSceneGUI",
                                                                                System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                    }
                }
            }
        }
예제 #5
0
        public static void DrawScriptField(UnityEditor.Editor editor)
        {
            using (new EditorGUI.DisabledScope(true))
            {
                if (editor.target is ScriptableObject so)
                {
                    EditorGUILayout.ObjectField("Script",
                                                MonoScript.FromScriptableObject(so), editor.GetType(), false);
                }

                if (editor.target is MonoBehaviour mb)
                {
                    EditorGUILayout.ObjectField("Script",
                                                MonoScript.FromMonoBehaviour(mb), editor.GetType(), false);
                }
            }
        }
예제 #6
0
        public override void OnDeactivate()
        {
            if (m_SettingsEditor != null)
            {
                var info = m_SettingsEditor.GetType().GetMethod("OnDisable");
                info?.Invoke(m_SettingsEditor, null);
            }

            m_SettingsEditor = null;
        }
        // Call this from Editor's OnInspectorGUI
        public void OnInspectorGUI()
        {
            m_ScratchComponentList.Clear();
            int numNullComponents = GetComponent(m_Stage, m_ScratchComponentList);

            // Have the edited components changed?
            int  numComponents = m_ScratchComponentList.Count;
            bool dirty         = numComponents != m_EditedComponents.Count;

            for (int i = 0; !dirty && i < numComponents; ++i)
            {
                dirty = m_ScratchComponentList[i] != m_EditedComponents[i];
            }
            if (dirty)
            {
                if (m_ComponentEditor != null)
                {
                    ActiveEditorRegistry.SetActiveEditor(m_ComponentEditor, false);
                    m_ComponentEditor.ResetTarget();
                    UnityEngine.Object.DestroyImmediate(m_ComponentEditor);
                }
                m_ComponentEditor           = null;
                m_ComponentEditorOnSceneGUI = null;

                m_EditedComponents.Clear();
                m_EditedComponents.AddRange(m_ScratchComponentList);
                m_IsMixedType = false;
                for (int i = 1; !m_IsMixedType && i < numComponents; ++i)
                {
                    m_IsMixedType = m_EditedComponents[i].GetType() != m_EditedComponents[i - 1].GetType();
                }
            }
            if (numNullComponents > 0 && numComponents > 0)
            {
                m_IsMixedType = true;
            }
            if (numComponents > 0 && m_ComponentEditor == null && !m_IsMixedType)
            {
                UnityEditor.Editor.CreateCachedEditor(m_EditedComponents.ToArray(), null, ref m_ComponentEditor);
                if (m_ComponentEditor != null)
                {
                    m_ComponentEditorOnSceneGUI = m_ComponentEditor.GetType().GetMethod("OnSceneGUI",
                                                                                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                }
            }
            m_StageSelection = GetPopupIndexForComponent(numComponents == 0 ? null : m_EditedComponents[0]);

            m_StageError = false;
            for (int i = 0; !m_StageError && i < numComponents; ++i)
            {
                m_StageError = !m_EditedComponents[i].IsValid;
            }

            DrawComponentInspector();
        }
예제 #8
0
        private static string CheckForValidCustomEditor(SerializedProperty property)
        {
            Type parentType = property.serializedObject.targetObject.GetType();

            UnityEditor.Editor parentEditor = UnityEditor.Editor.CreateEditor(property.serializedObject.targetObject);
            Type parentEditorType           = parentEditor.GetType();
            Type assignedEditorType         = GetAttributeValue(parentEditorType, (CustomEditor a) => GetField <Type>(a, "m_InspectedType"));
            bool validCustomEditor          = assignedEditorType == parentType;

            return(validCustomEditor ? "" : GetErrorInfo(property));
        }
예제 #9
0
 public void OnPositionDragged(Vector3 delta)
 {
     if (mComponentEditor != null)
     {
         MethodInfo mi = mComponentEditor.GetType().GetMethod("OnVcamPositionDragged"
                                                              , BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
         if (mi != null && mComponentEditor.target != null)
         {
             mi.Invoke(mComponentEditor, new object[] { delta });
         }
     }
 }
예제 #10
0
        void OnDisable()
        {
            //When OnDisable is called, the default editor we created should be destroyed to avoid memory leakage.
            //Also, make sure to call any required methods like OnDisable
            MethodInfo disableMethod = defaultEditor.GetType().GetMethod("OnDisable", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

            if (disableMethod != null)
            {
                disableMethod.Invoke(defaultEditor, null);
            }
            DestroyImmediate(defaultEditor);
        }
예제 #11
0
        public void StartEditing(EditMode.SceneViewEditMode mode, UnityEditor.Editor caller)
        {
            if (mode == EditMode.SceneViewEditMode.None || _caller == caller)
            {
                return;
            }
            Type editorType;

            if (!_editors.TryGetValue(mode, out editorType))
            {
                if (SPSettings.Current.DebugMode)
                {
                    Debug.LogErrorFormat("Editor for mode {0} was not found!", mode);
                }
                return;
            }
            _caller = caller;
            _editor = UnityEditor.Editor.CreateEditor(
                SplineBridge.GetUnserializedSpline(caller.serializedObject), editorType);
            editorType            = _editor.GetType();
            _onSceneGUIMethodInfo = editorType.GetMethod("OnSceneGUI",
                                                         BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.InvokeMethod);
            if (_onSceneGUIMethodInfo == null)
            {
                Debug.LogErrorFormat(
                    "Editor {0} has no method OnSceneGUI for view updating. Editing can not be processed.",
                    _editor.GetType().Name);
                _editor = null;
                _caller = null;
                return;
            }

            SceneView.onSceneGUIDelegate += OnSceneGuiDelegate;
            Tools.hidden = true;
            if (SPSettings.Current.DebugMode)
            {
                Debug.LogFormat("Editor {0} enabled for editing {1}",
                                _editor.GetType().Name, _editor.target);
            }
        }
예제 #12
0
    /// <summary>
    /// Connect the project tags with this object.
    /// </summary>
    private void Connect()
    {
        // Initializes the project with this object
        UnityEditor.Editor _thisEditor = UnityEditor.Editor.CreateEditor(this);

        if (!_thisEditor)
        {
            return;
        }

        _thisEditor.GetType().InvokeMember("ConnectProjectTags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic, null, _thisEditor, null);

        // Destroy the created editor
        DestroyImmediate(_thisEditor);
    }
예제 #13
0
        void OnDisable()
        {
            // Note: When OnDisable is called, the default editor we created should be destroyed to
            // avoid memory leakage. We also call any required methods like OnDisable.

            BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;

            MethodInfo disableMethod = defaultEditor.GetType().GetMethod("OnDisable", flags);

            if (disableMethod != null)
            {
                disableMethod.Invoke(defaultEditor, null);
            }

            DestroyImmediate(defaultEditor);
        }
예제 #14
0
        private static bool EditorForMultiEditingChanged(Editor editor, Object target)
        {
            if (editor.targets.Length <= 1)
            {
                return(false);
            }

            var currentEditorType  = editor.GetType();
            var expectedEditorType = CustomEditorAttributes.FindCustomEditorType(target, true);

            // Going from generic to generic inspector for multi editing is correctly handled.
            if (editor is GenericInspector && expectedEditorType == null)
            {
                return(false);
            }
            return(currentEditorType != expectedEditorType);
        }
예제 #15
0
        private bool Init(Object obj, EditorFeatures requirements)
        {
            editor = Editor.CreateEditor(obj);
            if (editor == null)
            {
                return(false);
            }

            if (requirements.HasFlag(EditorFeatures.PreviewGUI) && !editor.HasPreviewGUI())
            {
                return(false);
            }

            var onSceneDragMi = editor.GetType().GetMethod("OnSceneDrag", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            var objs           = new[] { obj };
            var rootEditorType = RootEditorUtils.FindRootEditor(objs);

            if (rootEditorType != null && onSceneDragMi == null)
            {
                // Create normal editor:
                editor        = RootEditorUtils.CreateNonRootEditor(objs);
                onSceneDragMi = editor.GetType().GetMethod("OnSceneDrag", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            }

            if (onSceneDragMi != null)
            {
                OnSceneDrag = (VoidDelegate)System.Delegate.CreateDelegate(typeof(VoidDelegate), editor, onSceneDragMi);
            }
            else if (requirements.HasFlag(EditorFeatures.OnSceneDrag))
            {
                return(false);
            }
            else
            {
                OnSceneDrag = DefaultOnSceneDrag;
            }

            return(true);
        }
예제 #16
0
        // Returns true when the 'editor' supports Softlock UI and the
        // user has Collaborate permissions.
        private bool HasSoftlockSupport(Editor editor)
        {
            if (!Collab.instance.IsCollabEnabledForCurrentProject() || editor == null || editor.targets.Length > 1)
            {
                return(false);
            }

            if (editor.target == null || !SoftLockData.AllowsSoftLocks(editor.target))
            {
                return(false);
            }

            // Support Scene and Game object Inspector headers, not others like MaterialEditor.
            bool hasSupport = true;
            Type editorType = editor.GetType();

            if (editorType != typeof(GameObjectInspector) && editorType != typeof(GenericInspector))
            {
                hasSupport = false;
            }

            return(hasSupport);
        }
        private bool HasSoftlockSupport(Editor editor)
        {
            bool result;

            if (!Collab.instance.IsCollabEnabledForCurrentProject() || editor == null || editor.targets.Length > 1)
            {
                result = false;
            }
            else if (editor.target == null || !SoftLockData.AllowsSoftLocks(editor.target))
            {
                result = false;
            }
            else
            {
                bool flag = true;
                Type type = editor.GetType();
                if (type != typeof(GameObjectInspector) && type != typeof(GenericInspector))
                {
                    flag = false;
                }
                result = flag;
            }
            return(result);
        }
예제 #18
0
        private void InitializeSpritePreview(UnityEditor.Editor editor, AnimationClip clip)
        {
            if (_HasInitializedSpritePreview)
            {
                return;
            }

            _HasInitializedSpritePreview = true;

            // Get the avatar preview.

            var field = editor.GetType().GetField("m_AvatarPreview", AnimancerEditorUtilities.InstanceBindings);

            if (field == null)
            {
                return;
            }

            var preview = field.GetValue(editor);

            if (preview == null)
            {
                return;
            }

            var previewType = preview.GetType();

            // Make sure a proper preview object isn't already assigned.

            var previewObject = previewType.GetProperty("PreviewObject", AnimancerEditorUtilities.InstanceBindings);

            if (previewObject == null)
            {
                return;
            }

            var previewGameObject = previewObject.GetValue(preview) as GameObject;

            if (previewGameObject != null &&
                previewGameObject.GetComponentInChildren <Renderer>() != null)
            {
                return;
            }

            // Get the SetPreview method.

            var method = previewType.GetMethod("SetPreview",
                                               AnimancerEditorUtilities.InstanceBindings, null,
                                               new Type[] { typeof(GameObject) }, null);

            if (method == null)
            {
                return;
            }

            // Get the Sprite from the target animation's first keyframe.

            var keyframes = GetSpriteReferences(clip);

            if (keyframes == null ||
                keyframes.Length == 0)
            {
                return;
            }

            var sprite = keyframes[0].value as Sprite;

            if (sprite == null)
            {
                return;
            }

            // Create an object with an Animator and SpriteRenderer.
            // The Sprite must be assigned for it to be accepted as the preview object.

            var gameObject = EditorUtility.CreateGameObjectWithHideFlags("SpritePreview",
                                                                         HideFlags.HideInHierarchy | HideFlags.DontSave);

            gameObject.AddComponent <Animator>();
            gameObject.AddComponent <SpriteRenderer>().sprite = sprite;

            // Set it as the preview object (which creates a copy of it) and destroy it.

            method.Invoke(preview, new object[] { gameObject });

            DestroyImmediate(gameObject);
        }
        /// <summary>
        /// Renders a non-editable object field and an editable dropdown of a profile.
        /// </summary>
        public static void RenderReadOnlyProfile(SerializedProperty property)
        {
            using (new EditorGUILayout.HorizontalScope())
            {
                EditorGUI.BeginDisabledGroup(true);
                EditorGUILayout.ObjectField(property.objectReferenceValue != null ? "" : property.displayName, property.objectReferenceValue, typeof(BaseMixedRealityProfile), false, GUILayout.ExpandWidth(true));
                EditorGUI.EndDisabledGroup();
            }

            if (property.objectReferenceValue != null)
            {
                bool showReadOnlyProfile = SessionState.GetBool(property.name + ".ReadOnlyProfile", false);

                using (new EditorGUI.IndentLevelScope())
                {
                    RenderFoldout(ref showReadOnlyProfile, property.displayName, () =>
                    {
                        using (new EditorGUI.IndentLevelScope())
                        {
                            UnityEditor.Editor subProfileEditor = CreateEditor(property.objectReferenceValue);
                            // If this is a default MRTK configuration profile, ask it to render as a sub-profile
                            if (typeof(BaseMixedRealityToolkitConfigurationProfileInspector).IsAssignableFrom(subProfileEditor.GetType()))
                            {
                                BaseMixedRealityToolkitConfigurationProfileInspector configProfile = (BaseMixedRealityToolkitConfigurationProfileInspector)subProfileEditor;
                                configProfile.RenderAsSubProfile = true;
                            }
                            subProfileEditor.OnInspectorGUI();
                        }
                    });
                }

                SessionState.SetBool(property.name + ".ReadOnlyProfile", showReadOnlyProfile);
            }
        }
예제 #20
0
        private void DrawPreviewGUI()
        {
            GUILayout.FlexibleSpace();

            if (_wavClipEditor == null)
            {
                _wavClipEditor = UnityEditor.Editor.CreateEditor(_wavClip);
            }

            if (_clipEditorBg == null)
            {
                _clipEditorBg = new GUIStyle();
                _clipEditorBg.normal.background = Texture2D.blackTexture;
            }

            int currentSample = GetSamplePosition();

            if (currentSample > 0)
            {
                // Playback position gets reset to zero after pausing. Save the last one to make
                // finding the desired loops easier.
                _lastPreviewSample = currentSample;
            }

            using (new EditorGUILayout.HorizontalScope())
            {
                GUILayout.Label("Preview");
                using (new EditorGUI.DisabledScope(_zoomLevel / 1.5f < 1.0f))
                {
                    if (GUILayout.Button("-"))
                    {
                        _zoomLevel /= 1.5f;
                    }
                }

                using (new EditorGUI.DisabledScope(_zoomLevel * 1.5f > 20.0f))
                {
                    if (GUILayout.Button("+"))
                    {
                        _zoomLevel *= 1.5f;
                    }
                }

                GUILayout.FlexibleSpace();
                _wavClipEditor.OnPreviewSettings();
            }

            using (var scrollView = new EditorGUILayout.ScrollViewScope(_previewScrollPos))
            {
                _previewScrollPos = scrollView.scrollPosition;
                _wavClipEditor.OnPreviewGUI(
                    GUILayoutUtility.GetRect(position.width * _zoomLevel, 100, GUILayout.ExpandWidth(false)),
                    _clipEditorBg);
            }

            using (new EditorGUILayout.HorizontalScope())
            {
                GUILayout.Label("Set Loop Point to Current Preview Position: ", GUILayout.ExpandWidth(false));
                GUILayout.Label(_useSeconds
                    ? SecondsToDurationString(SamplesToSeconds(_lastPreviewSample))
                    : _lastPreviewSample.ToString(),
                                GUILayout.Width(80));

                if (GUILayout.Button("Start", GUILayout.Width(80)))
                {
                    _wavData.GetOrAddFirstLoop().StartSample = _lastPreviewSample;
                }

                if (GUILayout.Button("End", GUILayout.Width(80)))
                {
                    _wavData.GetOrAddFirstLoop().EndSample = _lastPreviewSample;
                }
            }

            // Enable looping by default
            _wavClipEditor.GetType()
            .GetField("s_Loop", BindingFlags.Static | BindingFlags.NonPublic)?
            .SetValue(null, true);
        }
        /// <summary>
        /// Renders a non-editable object field and an editable dropdown of a profile.
        /// </summary>
        /// <param name="property"></param>
        /// <returns></returns>
        public static void RenderReadOnlyProfile(SerializedProperty property)
        {
            EditorGUILayout.BeginHorizontal();

            EditorGUI.BeginDisabledGroup(true);
            EditorGUILayout.ObjectField(property.objectReferenceValue != null ? "" : property.displayName, property.objectReferenceValue, typeof(BaseMixedRealityProfile), false, GUILayout.ExpandWidth(true));
            EditorGUI.EndDisabledGroup();

            EditorGUILayout.EndHorizontal();

            if (property.objectReferenceValue != null)
            {
                UnityEditor.Editor subProfileEditor = UnityEditor.Editor.CreateEditor(property.objectReferenceValue);

                // If this is a default MRTK configuration profile, ask it to render as a sub-profile
                if (typeof(BaseMixedRealityToolkitConfigurationProfileInspector).IsAssignableFrom(subProfileEditor.GetType()))
                {
                    BaseMixedRealityToolkitConfigurationProfileInspector configProfile = (BaseMixedRealityToolkitConfigurationProfileInspector)subProfileEditor;
                    configProfile.RenderAsSubProfile = true;
                }

                EditorGUILayout.BeginHorizontal();
                EditorGUI.indentLevel++;
                EditorGUILayout.BeginVertical(EditorStyles.helpBox);
                subProfileEditor.OnInspectorGUI();
                EditorGUILayout.Space();
                EditorGUILayout.EndVertical();
                EditorGUI.indentLevel--;
                EditorGUILayout.EndHorizontal();
            }
        }
        /// <summary>
        /// Renders a <see cref="Microsoft.MixedReality.Toolkit.BaseMixedRealityProfile"/>.
        /// </summary>
        /// <param name="property">the <see cref="Microsoft.MixedReality.Toolkit.BaseMixedRealityProfile"/> property.</param>
        /// <param name="showAddButton">If true, draw the clone button, if false, don't</param>
        /// <param name="renderProfileInBox">if true, render box around profile content, if false, don't</param>
        /// <param name="serviceType">Optional service type to limit available profile types.</param>
        /// <returns>True, if the profile changed.</returns>
        private static bool RenderProfileInternal(SerializedProperty property, Type profileType,
                                                  bool showAddButton, bool renderProfileInBox, Type serviceType = null)
        {
            var  profile   = property.serializedObject.targetObject as BaseMixedRealityProfile;
            bool changed   = false;
            var  oldObject = property.objectReferenceValue;

            if (profileType != null && !profileType.IsSubclassOf(typeof(BaseMixedRealityProfile)) && profileType != typeof(BaseMixedRealityProfile))
            {
                // If they've drag-and-dropped a non-profile scriptable object, set it to null.
                profileType = null;
            }

            // If we're constraining this to a service type, check whether the profile is valid
            // If it isn't, issue a warning.
            if (serviceType != null && oldObject != null)
            {
                if (!IsProfileForService(oldObject.GetType(), serviceType))
                {
                    EditorGUILayout.HelpBox("This profile is not supported for " + serviceType.Name + ". Using an unsupported service may result in unexpected behavior.", MessageType.Warning);
                }
            }

            // Find the profile type so we can limit the available object field options
            if (serviceType != null)
            {
                // If GetProfileTypesForService has a count greater than one, then it won't be possible to use
                // EditorGUILayout.ObjectField to restrict the set of profiles to a single type - in this
                // case all profiles of BaseMixedRealityProfile will be visible in the picker.
                //
                // However in the case where there is just a single profile type for the service, we can improve
                // upon the user experience by limiting the set of things that show in the picker by restricting
                // the set of profiles listed to only that type.
                profileType = GetProfileTypesForService(serviceType).FirstOrDefault();
            }

            // If the profile type is still null, just set it to base profile type
            if (profileType == null)
            {
                profileType = typeof(BaseMixedRealityProfile);
            }

            // Begin the horizontal group
            EditorGUILayout.BeginHorizontal();

            // Draw the object field with an empty label - label is kept in the foldout
            property.objectReferenceValue = EditorGUILayout.ObjectField(oldObject != null ? "" : property.displayName, oldObject, profileType, false, GUILayout.ExpandWidth(true));
            changed = (property.objectReferenceValue != oldObject);

            // Draw the clone button
            if (property.objectReferenceValue == null)
            {
                var profileTypeName = property.type.Replace("PPtr<$", string.Empty).Replace(">", string.Empty);
                if (showAddButton && IsConcreteProfileType(profileTypeName))
                {
                    if (GUILayout.Button(NewProfileContent, EditorStyles.miniButton, GUILayout.Width(20f)))
                    {
                        Debug.Assert(profileTypeName != null, "No Type Found");

                        ScriptableObject instance = CreateInstance(profileTypeName);
                        var newProfile            = instance.CreateAsset(AssetDatabase.GetAssetPath(Selection.activeObject)) as BaseMixedRealityProfile;
                        property.objectReferenceValue = newProfile;
                        property.serializedObject.ApplyModifiedProperties();
                        changed = true;
                    }
                }
            }
            else
            {
                var renderedProfile = property.objectReferenceValue as BaseMixedRealityProfile;
                Debug.Assert(renderedProfile != null);
                Debug.Assert(profile != null, "No profile was set in OnEnable. Did you forget to call base.OnEnable in a derived profile class?");

                if (GUILayout.Button(new GUIContent("Clone", "Replace with a copy of the default profile."), EditorStyles.miniButton, GUILayout.Width(42f)))
                {
                    MixedRealityProfileCloneWindow.OpenWindow(profile, renderedProfile, property);
                }
            }

            EditorGUILayout.EndHorizontal();

            if (property.objectReferenceValue != null)
            {
                UnityEditor.Editor subProfileEditor = UnityEditor.Editor.CreateEditor(property.objectReferenceValue);

                // If this is a default MRTK configuration profile, ask it to render as a sub-profile
                if (typeof(BaseMixedRealityToolkitConfigurationProfileInspector).IsAssignableFrom(subProfileEditor.GetType()))
                {
                    BaseMixedRealityToolkitConfigurationProfileInspector configProfile = (BaseMixedRealityToolkitConfigurationProfileInspector)subProfileEditor;
                    configProfile.RenderAsSubProfile = true;
                }

                var subProfile = property.objectReferenceValue as BaseMixedRealityProfile;
                if (subProfile != null && !subProfile.IsCustomProfile)
                {
                    EditorGUILayout.HelpBox("Clone this default profile to edit properties below", MessageType.Warning);
                }

                if (renderProfileInBox)
                {
                    EditorGUILayout.BeginVertical(EditorStyles.helpBox);
                }
                else
                {
                    EditorGUILayout.BeginVertical();
                }

                EditorGUILayout.Space();
                subProfileEditor.OnInspectorGUI();
                EditorGUILayout.Space();

                EditorGUILayout.EndVertical();
            }

            return(changed);
        }
예제 #23
0
        private static void OnFinishedHeaderGUI(UnityEditor.Editor editor)
        {
            if (editor.GetType() == typeof(MaterialEditor))
            {
                return;
            }
            if (!Container.GetLockSettings().IsEnabled)
            {
                return;
            }
            if (!Locker.HasFetched)
            {
                return;
            }
            if (!Locker.AreAssetTypesValid(editor.targets))
            {
                return;
            }

            var isLockedByMe          = Locker.AreAllAssetsLockedByMe(editor.targets);
            var isLockedBySomeoneElse = Locker.IsAnyAssetLockedBySomeoneElse(editor.targets);
            var isLockedNowButUnlockedAtLaterCommit = Locker.IsAnyAssetLockedNowButUnlockedAtLaterCommit(editor.targets);

            using (new GUILayout.HorizontalScope())
            {
                EditorGUILayout.LabelField("Lock", sm_lockLabelStyle, GUILayout.Width(44));
                using (new EditorGUI.DisabledGroupScope(isLockedByMe || isLockedBySomeoneElse || isLockedNowButUnlockedAtLaterCommit))
                {
                    if (GUILayout.Button(new GUIContent(Constants.LockName), EditorStyles.miniButton))
                    {
                        Locker.TryLockAssets(editor.targets, null, (errorMessage) =>
                        {
                            EditorUtility.DisplayDialog("Asset locking failed", "Asset locking failed\n" + errorMessage, "OK");
                        });
                    }
                }
                using (new EditorGUI.DisabledGroupScope(!isLockedByMe))
                {
                    if (GUILayout.Button(new GUIContent(Constants.RevertName), EditorStyles.miniButton))
                    {
                        Locker.TryRevertAssetLocks(editor.targets, null, (errorMessage) =>
                        {
                            EditorUtility.DisplayDialog("Asset reverting failed", "Asset reverting failed\n" + errorMessage, "OK");
                        });
                    }
                    if (GUILayout.Button(new GUIContent(Constants.FinishName), EditorStyles.miniButton))
                    {
                        Locker.TryFinishLockingAssets(editor.targets, null, (errorMessage) =>
                        {
                            EditorUtility.DisplayDialog("Asset finishing failed", "Asset finishing failed\n" + errorMessage, "OK");
                        });
                    }
                }
                if (GUILayout.Button(new GUIContent(Constants.HistoryName), EditorStyles.miniButton))
                {
                    HistoryWindow.Show(editor.target);
                }
            }

            if (isLockedByMe || isLockedBySomeoneElse || isLockedNowButUnlockedAtLaterCommit)
            {
                var hasMultipleLockers = false;
                var locker             = Locker.GetAssetLocker(editor.targets[0]);
                for (var i = 1; i < editor.targets.Length; i++)
                {
                    if (locker != Locker.GetAssetLocker(editor.targets[1]))
                    {
                        hasMultipleLockers = true;
                        break;
                    }
                }
                if (!string.IsNullOrEmpty(locker))
                {
                    LockDrawer.TryDrawLock(sm_headerRect, editor.target, LockDrawer.DrawType.LargeIcon);
                    EditorGUILayout.LabelField("Asset" + (editor.targets.Length > 1 ? "s" : "") + " locked by " + (hasMultipleLockers ? "multiple users" : locker), EditorStyles.boldLabel);
                    if (isLockedNowButUnlockedAtLaterCommit)
                    {
                        var hasMultipleUnlockShas = false;
                        var sha = Locker.GetAssetUnlockCommitShaShort(editor.targets[0]);
                        for (var i = 1; i < editor.targets.Length; i++)
                        {
                            if (sha != Locker.GetAssetUnlockCommitShaShort(editor.targets[1]))
                            {
                                hasMultipleUnlockShas = true;
                                break;
                            }
                        }
                        if (!string.IsNullOrEmpty(sha))
                        {
                            if (hasMultipleUnlockShas)
                            {
                                EditorGUILayout.LabelField("(Unlocked at multiple commits)");
                            }
                            else
                            {
                                EditorGUILayout.LabelField("(Unlocked at commit " + sha + ")");
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Draws an editor for a profile object.
        /// </summary>
        public static void DrawSubProfileEditor(Object profileObject, bool renderProfileInBox)
        {
            if (profileObject == null)
            {
                return;
            }

            UnityEditor.Editor subProfileEditor = null;
            if (!profileEditorCache.TryGetValue(profileObject, out subProfileEditor))
            {
                subProfileEditor = UnityEditor.Editor.CreateEditor(profileObject);
                profileEditorCache.Add(profileObject, subProfileEditor);
            }

            // If this is a default MRTK configuration profile, ask it to render as a sub-profile
            if (typeof(BaseMixedRealityToolkitConfigurationProfileInspector).IsAssignableFrom(subProfileEditor.GetType()))
            {
                BaseMixedRealityToolkitConfigurationProfileInspector configProfile = (BaseMixedRealityToolkitConfigurationProfileInspector)subProfileEditor;
                configProfile.RenderAsSubProfile = true;
            }

            var subProfile = profileObject as BaseMixedRealityProfile;
            if (subProfile != null && !subProfile.IsCustomProfile)
            {
                string msg = MixedRealityProjectPreferences.LockProfiles ? CloneProfileHelpLockedLabel : CloneProfileHelpLabel;
                EditorGUILayout.HelpBox(msg, MessageType.Warning);
            }

            if (renderProfileInBox)
            {
                EditorGUILayout.BeginVertical(EditorStyles.helpBox);
            }
            else
            {
                EditorGUILayout.BeginVertical();
            }

            EditorGUILayout.Space();
            subProfileEditor.OnInspectorGUI();
            EditorGUILayout.Space();

            EditorGUILayout.EndVertical();
        }
예제 #25
0
        private static bool RenderProfileInternal(SerializedProperty property, GUIContent guiContent, bool showAddButton, Type serviceType = null)
        {
            profile = property.serializedObject.targetObject as BaseMixedRealityProfile;

            bool changed = false;

            var oldObject = property.objectReferenceValue;

            // If we're constraining this to a service type, check whether the profile is valid
            // If it isn't, issue a warning.
            if (serviceType != null && oldObject != null)
            {
                bool profileTypeIsValid = false;

                foreach (MixedRealityServiceProfileAttribute serviceProfileAttribute in oldObject.GetType().GetCustomAttributes(typeof(MixedRealityServiceProfileAttribute), true))
                {
                    if (serviceProfileAttribute.ServiceType.IsAssignableFrom(serviceType))
                    {
                        profileTypeIsValid = true;
                        break;
                    }
                }

                if (!profileTypeIsValid)
                {
                    EditorGUILayout.HelpBox("This profile is not supported for " + serviceType.Name + ". Using an unsupported service may result in unexpected behavior.", MessageType.Warning);
                }
            }

            EditorGUILayout.BeginHorizontal();

            if (guiContent == null)
            {
                EditorGUILayout.PropertyField(property);
            }
            else
            {
                EditorGUILayout.PropertyField(property, guiContent);
            }

            if (property.objectReferenceValue == null)
            {
                if (showAddButton)
                {
                    if (GUILayout.Button(NewProfileContent, EditorStyles.miniButton, GUILayout.Width(20f)))
                    {
                        var profileTypeName = property.type.Replace("PPtr<$", string.Empty).Replace(">", string.Empty);
                        Debug.Assert(profileTypeName != null, "No Type Found");

                        ScriptableObject instance = CreateInstance(profileTypeName);
                        var newProfile            = instance.CreateAsset(AssetDatabase.GetAssetPath(Selection.activeObject)) as BaseMixedRealityProfile;
                        property.objectReferenceValue = newProfile;
                        property.serializedObject.ApplyModifiedProperties();
                        changed = true;
                    }
                }
            }
            else
            {
                var renderedProfile = property.objectReferenceValue as BaseMixedRealityProfile;
                Debug.Assert(renderedProfile != null);
                Debug.Assert(profile != null, "No profile was set in OnEnable. Did you forget to call base.OnEnable in a derived profile class?");

                if (GUILayout.Button(new GUIContent("Clone", "Replace with a copy of the default profile."), EditorStyles.miniButton, GUILayout.Width(42f)))
                {
                    MixedRealityProfileCloneWindow.OpenWindow(profile, renderedProfile, property);
                }
            }

            EditorGUILayout.EndHorizontal();

            // Check fields within profile for other nested profiles
            // Draw them when found
            if (property.objectReferenceValue != null)
            {
                Type profileType = property.objectReferenceValue.GetType();
                if (typeof(BaseMixedRealityProfile).IsAssignableFrom(profileType))
                {
                    string showFoldoutKey = GetSubProfileDropdownKey(property);
                    bool   showFoldout    = SessionState.GetBool(showFoldoutKey, false);
                    showFoldout = EditorGUILayout.Foldout(showFoldout, showFoldout ? "Hide " + property.displayName + " contents" : "Show " + property.displayName + " contents", true);

                    if (showFoldout)
                    {
                        UnityEditor.Editor subProfileEditor = UnityEditor.Editor.CreateEditor(property.objectReferenceValue);

                        // If this is a default MRTK configuration profile, ask it to render as a sub-profile
                        if (typeof(BaseMixedRealityToolkitConfigurationProfileInspector).IsAssignableFrom(subProfileEditor.GetType()))
                        {
                            BaseMixedRealityToolkitConfigurationProfileInspector configProfile = (BaseMixedRealityToolkitConfigurationProfileInspector)subProfileEditor;
                            configProfile.RenderAsSubProfile = true;
                        }

                        EditorGUI.indentLevel++;
                        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
                        subProfileEditor.OnInspectorGUI();

                        EditorGUILayout.Space();
                        EditorGUILayout.Space();

                        EditorGUILayout.EndVertical();
                        EditorGUI.indentLevel--;
                    }

                    SessionState.SetBool(showFoldoutKey, showFoldout);
                }
            }

            return(changed);
        }