protected static BaseMixedRealityProfile CreateCustomProfile(BaseMixedRealityProfile sourceProfile) { if (sourceProfile == null) { return(null); } ScriptableObject newProfile = CreateInstance(sourceProfile.GetType().ToString()); BaseMixedRealityProfile targetProfile = newProfile.CreateAsset("Assets/MixedRealityToolkit.Generated/CustomProfiles") as BaseMixedRealityProfile; Debug.Assert(targetProfile != null); EditorUtility.CopySerialized(sourceProfile, targetProfile); var serializedProfile = new SerializedObject(targetProfile); serializedProfile.FindProperty(IsCustomProfileProperty).boolValue = true; serializedProfile.ApplyModifiedProperties(); AssetDatabase.SaveAssets(); if (!sourceProfile.IsCustomProfile) { // For now we only replace it if it's the master configuration profile. // Sub-profiles are easy to update in the master configuration inspector. if (MixedRealityToolkit.Instance.ActiveProfile.GetType() == targetProfile.GetType()) { UnityEditor.Undo.RecordObject(MixedRealityToolkit.Instance, "Copy & Customize Profile"); MixedRealityToolkit.Instance.ActiveProfile = targetProfile as MixedRealityToolkitConfigurationProfile; } } return(targetProfile); }
protected static bool RenderProfile(SerializedProperty property) { bool changed = false; EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(property); if (property.objectReferenceValue == null) { 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 (!renderedProfile.IsCustomProfile && profile.IsCustomProfile) { if (GUILayout.Button(new GUIContent("</>", "Replace with a copy of the default profile."), EditorStyles.miniButton, GUILayout.Width(32f))) { profileToCopy = renderedProfile; 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(); PasteProfileValuesDelay(newProfile); changed = true; } } } EditorGUILayout.EndHorizontal(); return(changed); }
private static BaseMixedRealityProfile CloneProfile(BaseMixedRealityProfile parentProfile, BaseMixedRealityProfile profileToClone, string childProfileTypeName, SerializedProperty childProperty, Object targetFolder, string profileName) { ScriptableObject instance = CreateInstance(childProfileTypeName); instance.name = string.IsNullOrEmpty(profileName) ? childProfileTypeName : profileName; string fileName = instance.name; string path = AssetDatabase.GetAssetPath(targetFolder); Debug.Log("Creating asset in path " + targetFolder); var newChildProfile = instance.CreateAsset(path, fileName) as BaseMixedRealityProfile; childProperty.objectReferenceValue = newChildProfile; childProperty.serializedObject.ApplyModifiedProperties(); return(newChildProfile); }
private static void RenderProfile(SerializedProperty property) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(property); if (property.objectReferenceValue == null) { if (GUILayout.Button(NewProfileContent, EditorStyles.miniButton)) { var profileTypeName = property.type.Replace("PPtr<$", string.Empty).Replace(">", string.Empty); Debug.Assert(profileTypeName != null, "No Type Found"); ScriptableObject profile = CreateInstance(profileTypeName); profile.CreateAsset(AssetDatabase.GetAssetPath(Selection.activeObject)); property.objectReferenceValue = profile; } } EditorGUILayout.EndHorizontal(); }
protected static async void CreateCopyProfileValues() { profileToCopy = profile; ScriptableObject newProfile = CreateInstance(profile.GetType().ToString()); profile = newProfile.CreateAsset("Assets/XRTK-Generated/CustomProfiles") as BaseMixedRealityProfile; Debug.Assert(profile != null); await new WaitUntil(() => profileToCopy != profile); Selection.activeObject = null; PasteProfileValues(); Selection.activeObject = profile; if (!profileToCopy.IsCustomProfile) { // For now we only replace it if it's the master configuration profile. // Sub-profiles are easy to update in the master configuration inspector. if (MixedRealityToolkit.Instance.ActiveProfile.GetType() == profile.GetType()) { MixedRealityToolkit.Instance.ActiveProfile = profile as MixedRealityToolkitConfigurationProfile; } } }
/// <summary> /// Attempts to find the asset associated to the instance of the <see cref="ScriptableObject"/>, if none is found a new asset is created. /// </summary> /// <param name="scriptableObject"><see cref="ScriptableObject"/> you want get or create an asset file for.</param> /// <param name="path">Optional path for the new asset.</param> /// <param name="fileName">Optional filename for the new asset.</param> /// <param name="ping">The new asset should be selected and opened in the inspector.</param> public static ScriptableObject GetOrCreateAsset(this ScriptableObject scriptableObject, string path, string fileName, bool ping) { return(!AssetDatabase.TryGetGUIDAndLocalFileIdentifier(scriptableObject, out var guid, out long _) ? scriptableObject.CreateAsset(path, fileName, ping) : AssetDatabase.LoadAssetAtPath <ScriptableObject>(AssetDatabase.GUIDToAssetPath(guid))); }
private static bool RenderProfileInternal(SerializedProperty property, GUIContent guiContent, bool showAddButton) { bool changed = false; EditorGUILayout.BeginHorizontal(); var oldObject = property.objectReferenceValue; if (guiContent == null) { EditorGUILayout.PropertyField(property); } else { EditorGUILayout.PropertyField(property, guiContent); } if (property.objectReferenceValue == null) { if (showAddButton && 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 (profile.IsCustomProfile && !renderedProfile.IsCustomProfile && GUILayout.Button(CopyProfileContent, EditorStyles.miniButton, GUILayout.Width(42f))) { profileToCopy = renderedProfile; var typeName = renderedProfile.GetType().Name; Debug.Assert(typeName != null, "No Type Found"); ScriptableObject instance = CreateInstance(typeName); var newProfile = instance.CreateAsset(AssetDatabase.GetAssetPath(Selection.activeObject)) as BaseMixedRealityProfile; property.objectReferenceValue = newProfile; property.serializedObject.ApplyModifiedProperties(); PasteProfileValuesDelay(newProfile); changed = true; } } if (oldObject != property.objectReferenceValue) { changed = true; } EditorGUILayout.EndHorizontal(); return(changed); }
public override void OnInspectorGUI() { serializedObject.Update(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(activeProfile); bool changed = EditorGUI.EndChangeCheck(); string commandName = Event.current.commandName; var allConfigProfiles = ScriptableObjectExtensions.GetAllInstances <MixedRealityToolkitConfigurationProfile>(); if (activeProfile.objectReferenceValue == null && currentPickerWindow == -1 && checkChange) { if (allConfigProfiles.Length > 1) { EditorUtility.DisplayDialog("Attention!", "You must choose a profile for the Mixed Reality Toolkit.", "OK"); currentPickerWindow = GUIUtility.GetControlID(FocusType.Passive); EditorGUIUtility.ShowObjectPicker <MixedRealityToolkitConfigurationProfile>(null, false, string.Empty, currentPickerWindow); } else if (allConfigProfiles.Length == 1) { activeProfile.objectReferenceValue = allConfigProfiles[0]; changed = true; Selection.activeObject = allConfigProfiles[0]; EditorGUIUtility.PingObject(allConfigProfiles[0]); } else { if (EditorUtility.DisplayDialog("Attention!", "No profiles were found for the Mixed Reality Toolkit.\n\n" + "Would you like to create one now?", "OK", "Later")) { ScriptableObject profile = CreateInstance(nameof(MixedRealityToolkitConfigurationProfile)); profile.CreateAsset("Assets/MixedRealityToolkit.Generated/CustomProfiles"); activeProfile.objectReferenceValue = profile; Selection.activeObject = profile; EditorGUIUtility.PingObject(profile); } } checkChange = false; } if (EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow) { switch (commandName) { case "ObjectSelectorUpdated": activeProfile.objectReferenceValue = EditorGUIUtility.GetObjectPickerObject(); changed = true; break; case "ObjectSelectorClosed": activeProfile.objectReferenceValue = EditorGUIUtility.GetObjectPickerObject(); currentPickerWindow = -1; changed = true; Selection.activeObject = activeProfile.objectReferenceValue; EditorGUIUtility.PingObject(activeProfile.objectReferenceValue); break; } } serializedObject.ApplyModifiedProperties(); if (changed) { MixedRealityToolkit.Instance.ResetConfiguration((MixedRealityToolkitConfigurationProfile)activeProfile.objectReferenceValue); } if (activeProfile.objectReferenceValue != null) { UnityEditor.Editor activeProfileEditor = CreateEditor(activeProfile.objectReferenceValue); activeProfileEditor.OnInspectorGUI(); } }
private static bool RenderProfileInternal(SerializedProperty property, GUIContent guiContent, bool showAddButton) { bool changed = false; EditorGUILayout.BeginHorizontal(); var oldObject = property.objectReferenceValue; 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 (!renderedProfile.IsCustomProfile && profile.IsCustomProfile) { if (GUILayout.Button(new GUIContent("</>", "Replace with a copy of the default profile."), EditorStyles.miniButton, GUILayout.Width(32f))) { profileToCopy = renderedProfile; var profileTypeName = property.objectReferenceValue.GetType().Name; 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(); PasteProfileValuesDelay(newProfile); changed = true; } } } if (oldObject != property.objectReferenceValue) { changed = true; } 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"); if (showFoldout) { Editor subProfileEditor = 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.BeginVertical(EditorStyles.helpBox); EditorGUI.indentLevel++; subProfileEditor.OnInspectorGUI(); EditorGUI.indentLevel--; EditorGUILayout.EndVertical(); } SessionState.SetBool(showFoldoutKey, showFoldout); } } return(changed); }
public override void OnInspectorGUI() { MixedRealityToolkit instance = (MixedRealityToolkit)target; if (MixedRealityToolkit.Instance == null && instance.isActiveAndEnabled) { // See if an active instance exists at all. If it doesn't register this instance preemptively. MixedRealityToolkit.SetActiveInstance(instance); } if (!instance.IsActiveInstance) { EditorGUILayout.HelpBox("This instance of the toolkit is inactive. There can only be one active instance loaded at any time.", MessageType.Warning); using (new EditorGUILayout.HorizontalScope()) { if (GUILayout.Button("Select Active Instance")) { UnityEditor.Selection.activeGameObject = MixedRealityToolkit.Instance.gameObject; } if (GUILayout.Button("Make this the Active Instance")) { MixedRealityToolkit.SetActiveInstance(instance); } } return; } serializedObject.Update(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(activeProfile); bool changed = EditorGUI.EndChangeCheck(); string commandName = Event.current.commandName; // If not profile is assigned, then warn user if (activeProfile.objectReferenceValue == null) { EditorGUILayout.HelpBox("MixedRealityToolkit cannot initialize unless an Active Profile is assigned!", MessageType.Error); if (GUILayout.Button("Assign MixedRealityToolkit Profile") || forceShowProfilePicker) { forceShowProfilePicker = false; var allConfigProfiles = ScriptableObjectExtensions.GetAllInstances <MixedRealityToolkitConfigurationProfile>(); // Shows the list of MixedRealityToolkitConfigurationProfiles in our project, // selecting the default profile by default (if it exists). if (allConfigProfiles.Length > 0) { currentPickerWindow = GUIUtility.GetControlID(FocusType.Passive); var defaultMRTKProfile = MixedRealityInspectorUtility.GetDefaultConfigProfile(allConfigProfiles); activeProfile.objectReferenceValue = defaultMRTKProfile; EditorGUIUtility.ShowObjectPicker <MixedRealityToolkitConfigurationProfile>(defaultMRTKProfile, false, string.Empty, currentPickerWindow); } else { if (EditorUtility.DisplayDialog("Attention!", "No profiles were found for the Mixed Reality Toolkit.\n\n" + "Would you like to create one now?", "OK", "Later")) { ScriptableObject profile = CreateInstance(nameof(MixedRealityToolkitConfigurationProfile)); profile.CreateAsset("Assets/MixedRealityToolkit.Generated/CustomProfiles"); activeProfile.objectReferenceValue = profile; EditorGUIUtility.PingObject(profile); } } } } // If user selects a new MRTK Active Profile, then update configuration if (EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow) { switch (commandName) { case "ObjectSelectorUpdated": activeProfile.objectReferenceValue = EditorGUIUtility.GetObjectPickerObject(); changed = true; break; case "ObjectSelectorClosed": activeProfile.objectReferenceValue = EditorGUIUtility.GetObjectPickerObject(); currentPickerWindow = -1; changed = true; break; } } serializedObject.ApplyModifiedProperties(); if (changed) { MixedRealityToolkit.Instance.ResetConfiguration((MixedRealityToolkitConfigurationProfile)activeProfile.objectReferenceValue); } if (activeProfile.objectReferenceValue != null) { UnityEditor.Editor activeProfileEditor = CreateEditor(activeProfile.objectReferenceValue); activeProfileEditor.OnInspectorGUI(); } }
public override void OnInspectorGUI() { var configurationProfile = (MixedRealityToolkitConfigurationProfile)target; serializedObject.Update(); RenderMixedRealityToolkitLogo(); if (!MixedRealityToolkit.IsInitialized) { EditorGUILayout.HelpBox("No Mixed Reality Toolkit found in scene.", MessageType.Warning); if (GUILayout.Button("Click here to add Mixed Reality Toolkit instance to scene")) { new GameObject("MixedRealityToolkit").AddComponent <MixedRealityToolkit>(); } } if (!configurationProfile.IsCustomProfile) { EditorGUILayout.HelpBox("The Mixed Reality Toolkit's core SDK profiles can be used to get up and running quickly.\n\n" + "You can use the default profiles provided, copy and customize the default profiles, or create your own.", MessageType.Warning); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Copy & Customize")) { var originalSelection = Selection.activeObject; CreateCustomProfile(target as BaseMixedRealityProfile); Selection.activeObject = originalSelection; } if (MixedRealityToolkit.IsInitialized) { if (GUILayout.Button("Create new profiles")) { ScriptableObject profile = CreateInstance(nameof(MixedRealityToolkitConfigurationProfile)); var newProfile = profile.CreateAsset("Assets/MixedRealityToolkit.Generated/CustomProfiles") as MixedRealityToolkitConfigurationProfile; UnityEditor.Undo.RecordObject(MixedRealityToolkit.Instance, "Create new profiles"); MixedRealityToolkit.Instance.ActiveProfile = newProfile; Selection.activeObject = newProfile; } } EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField(string.Empty, GUI.skin.horizontalSlider); } bool isGUIEnabled = !IsProfileLock((BaseMixedRealityProfile)target); GUI.enabled = isGUIEnabled; EditorGUI.BeginChangeCheck(); bool changed = false; // Experience configuration ExperienceScale experienceScale = (ExperienceScale)targetExperienceScale.intValue; EditorGUILayout.PropertyField(targetExperienceScale, TargetScaleContent); string scaleDescription = GetExperienceDescription(experienceScale); if (!string.IsNullOrEmpty(scaleDescription)) { EditorGUILayout.HelpBox(scaleDescription, MessageType.Info); EditorGUILayout.Space(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Width(100)); GUI.enabled = true; // Force enable so we can view profile defaults SelectedProfileTab = GUILayout.SelectionGrid(SelectedProfileTab, ProfileTabTitles, 1, EditorStyles.boldLabel, GUILayout.MaxWidth(125)); GUI.enabled = isGUIEnabled; EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(EditorStyles.helpBox); using (new EditorGUI.IndentLevelScope()) { changed |= RenderProfileFuncs[SelectedProfileTab](); } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); if (!changed) { changed |= EditorGUI.EndChangeCheck(); } serializedObject.ApplyModifiedProperties(); GUI.enabled = true; if (changed && MixedRealityToolkit.IsInitialized) { EditorApplication.delayCall += () => MixedRealityToolkit.Instance.ResetConfiguration(configurationProfile); } }
public override void OnInspectorGUI() { MixedRealityInspectorUtility.RenderMixedRealityToolkitLogo(); serializedObject.Update(); if (!MixedRealityToolkit.IsInitialized) { EditorGUILayout.HelpBox("Unable to find Mixed Reality Toolkit!", MessageType.Error); return; } if (!configurationProfile.IsCustomProfile) { EditorGUILayout.HelpBox("The Mixed Reality Toolkit's core SDK profiles can be used to get up and running quickly.\n\n" + "You can use the default profiles provided, copy and customize the default profiles, or create your own.", MessageType.Warning); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Copy & Customize")) { CreateCopyProfileValues(); } if (GUILayout.Button("Create new profiles")) { ScriptableObject profile = CreateInstance(nameof(MixedRealityToolkitConfigurationProfile)); var newProfile = profile.CreateAsset("Assets/XRTK.Generated/CustomProfiles") as MixedRealityToolkitConfigurationProfile; MixedRealityToolkit.Instance.ActiveProfile = newProfile; Selection.activeObject = newProfile; } EditorGUILayout.EndHorizontal(); } // We don't call the CheckLock method so won't get a duplicate message. if (MixedRealityPreferences.LockProfiles && !((BaseMixedRealityProfile)target).IsCustomProfile) { GUI.enabled = false; } var previousLabelWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 160f; EditorGUI.BeginChangeCheck(); bool changed = false; // Camera Profile configuration GUILayout.Space(12f); EditorGUILayout.LabelField("Camera Settings", EditorStyles.boldLabel); EditorGUILayout.PropertyField(enableCameraProfile); changed |= RenderProfile(cameraProfile); // Input System configuration GUILayout.Space(12f); EditorGUILayout.LabelField("Input System Settings", EditorStyles.boldLabel); EditorGUILayout.PropertyField(enableInputSystem); EditorGUILayout.PropertyField(inputSystemType); changed |= RenderProfile(inputSystemProfile); // Boundary System configuration GUILayout.Space(12f); EditorGUILayout.LabelField("Boundary System Settings", EditorStyles.boldLabel); EditorGUILayout.PropertyField(enableBoundarySystem); EditorGUILayout.PropertyField(boundarySystemType); changed |= RenderProfile(boundaryVisualizationProfile); // Teleport System configuration GUILayout.Space(12f); EditorGUILayout.LabelField("Teleport System Settings", EditorStyles.boldLabel); EditorGUILayout.PropertyField(enableTeleportSystem); EditorGUILayout.PropertyField(teleportSystemType); // Spatial Awareness System configuration GUILayout.Space(12f); EditorGUILayout.LabelField("Spatial Awareness System Settings", EditorStyles.boldLabel); EditorGUILayout.PropertyField(enableSpatialAwarenessSystem); EditorGUILayout.PropertyField(spatialAwarenessSystemType); changed |= RenderProfile(spatialAwarenessProfile); // Networking System configuration GUILayout.Space(12f); EditorGUILayout.LabelField("Networking System Settings", EditorStyles.boldLabel); EditorGUILayout.PropertyField(enableNetworkingSystem); EditorGUILayout.PropertyField(networkingSystemType); changed |= RenderProfile(networkingSystemProfile); // Diagnostics System configuration GUILayout.Space(12f); EditorGUILayout.LabelField("Diagnostics System Settings", EditorStyles.boldLabel); EditorGUILayout.PropertyField(enableDiagnosticsSystem); EditorGUILayout.PropertyField(diagnosticsSystemType); changed |= RenderProfile(diagnosticsSystemProfile); GUILayout.Space(12f); EditorGUILayout.LabelField("Additional Service Providers", EditorStyles.boldLabel); changed |= RenderProfile(registeredServiceProvidersProfile); if (!changed) { changed |= EditorGUI.EndChangeCheck(); } EditorGUIUtility.labelWidth = previousLabelWidth; serializedObject.ApplyModifiedProperties(); if (changed) { EditorApplication.delayCall += () => MixedRealityToolkit.Instance.ResetConfiguration(configurationProfile); } }
/// <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); }
public override void OnInspectorGUI() { MixedRealityToolkit instance = (MixedRealityToolkit)target; if (MixedRealityToolkit.Instance == null) { // See if an active instance exists at all. If it doesn't register this instance pre-emptively. MixedRealityToolkit.SetActiveInstance(instance); } if (!instance.IsActiveInstance) { EditorGUILayout.HelpBox("This instance of the toolkt is inactive. There can only be one active instance loaded at any time.", MessageType.Warning); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Select Active Instance")) { UnityEditor.Selection.activeGameObject = MixedRealityToolkit.Instance.gameObject; } if (GUILayout.Button("Make this the Active Instance")) { MixedRealityToolkit.SetActiveInstance(instance); } EditorGUILayout.EndHorizontal(); return; } serializedObject.Update(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(activeProfile); bool changed = EditorGUI.EndChangeCheck(); string commandName = Event.current.commandName; var allConfigProfiles = ScriptableObjectExtensions.GetAllInstances <MixedRealityToolkitConfigurationProfile>(); if (activeProfile.objectReferenceValue == null && currentPickerWindow == -1 && checkChange && !BuildPipeline.isBuildingPlayer) { if (allConfigProfiles.Length > 1) { EditorUtility.DisplayDialog("Attention!", "You must choose a profile for the Mixed Reality Toolkit.", "OK"); currentPickerWindow = GUIUtility.GetControlID(FocusType.Passive); // Shows the list of MixedRealityToolkitConfigurationProfiles in our project, // selecting the default profile by default (if it exists). EditorGUIUtility.ShowObjectPicker <MixedRealityToolkitConfigurationProfile>(GetDefaultProfile(allConfigProfiles), false, string.Empty, currentPickerWindow); } else if (allConfigProfiles.Length == 1) { activeProfile.objectReferenceValue = allConfigProfiles[0]; changed = true; Selection.activeObject = allConfigProfiles[0]; EditorGUIUtility.PingObject(allConfigProfiles[0]); } else { if (EditorUtility.DisplayDialog("Attention!", "No profiles were found for the Mixed Reality Toolkit.\n\n" + "Would you like to create one now?", "OK", "Later")) { ScriptableObject profile = CreateInstance(nameof(MixedRealityToolkitConfigurationProfile)); profile.CreateAsset("Assets/MixedRealityToolkit.Generated/CustomProfiles"); activeProfile.objectReferenceValue = profile; Selection.activeObject = profile; EditorGUIUtility.PingObject(profile); } } checkChange = false; } if (EditorGUIUtility.GetObjectPickerControlID() == currentPickerWindow) { switch (commandName) { case "ObjectSelectorUpdated": activeProfile.objectReferenceValue = EditorGUIUtility.GetObjectPickerObject(); changed = true; break; case "ObjectSelectorClosed": activeProfile.objectReferenceValue = EditorGUIUtility.GetObjectPickerObject(); currentPickerWindow = -1; changed = true; Selection.activeObject = activeProfile.objectReferenceValue; EditorGUIUtility.PingObject(activeProfile.objectReferenceValue); break; } } serializedObject.ApplyModifiedProperties(); if (changed) { MixedRealityToolkit.Instance.ResetConfiguration((MixedRealityToolkitConfigurationProfile)activeProfile.objectReferenceValue); } if (activeProfile.objectReferenceValue != null) { UnityEditor.Editor activeProfileEditor = CreateEditor(activeProfile.objectReferenceValue); activeProfileEditor.OnInspectorGUI(); } }
public override void OnInspectorGUI() { var configurationProfile = (MixedRealityToolkitConfigurationProfile)target; serializedObject.Update(); RenderMixedRealityToolkitLogo(); if (!MixedRealityToolkit.IsInitialized) { EditorGUILayout.HelpBox("Unable to find Mixed Reality Toolkit!", MessageType.Error); return; } if (!configurationProfile.IsCustomProfile) { EditorGUILayout.HelpBox("The Mixed Reality Toolkit's core SDK profiles can be used to get up and running quickly.\n\n" + "You can use the default profiles provided, copy and customize the default profiles, or create your own.", MessageType.Warning); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Copy & Customize")) { CreateCopyProfileValues(); } if (GUILayout.Button("Create new profiles")) { ScriptableObject profile = CreateInstance(nameof(MixedRealityToolkitConfigurationProfile)); var newProfile = profile.CreateAsset("Assets/MixedRealityToolkit.Generated/CustomProfiles") as MixedRealityToolkitConfigurationProfile; MixedRealityToolkit.Instance.ActiveProfile = newProfile; Selection.activeObject = newProfile; } EditorGUILayout.EndHorizontal(); } // We don't call the CheckLock method so won't get a duplicate message. if (MixedRealityPreferences.LockProfiles && !((BaseMixedRealityProfile)target).IsCustomProfile) { GUI.enabled = false; } var previousLabelWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 160f; EditorGUI.BeginChangeCheck(); bool changed = false; // Experience configuration EditorGUILayout.Space(); ExperienceScale experienceScale = (ExperienceScale)targetExperienceScale.intValue; showExperienceProperties = EditorGUILayout.Foldout(showExperienceProperties, "Experience Settings", true); if (showExperienceProperties) { using (new EditorGUI.IndentLevelScope()) { EditorGUILayout.PropertyField(targetExperienceScale, TargetScaleContent); string scaleDescription = string.Empty; switch (experienceScale) { case ExperienceScale.OrientationOnly: scaleDescription = "The user is stationary. Position data does not change."; break; case ExperienceScale.Seated: scaleDescription = "The user is stationary and seated. The origin of the world is at a neutral head-level position."; break; case ExperienceScale.Standing: scaleDescription = "The user is stationary and standing. The origin of the world is on the floor, facing forward."; break; case ExperienceScale.Room: scaleDescription = "The user is free to move about the room. The origin of the world is on the floor, facing forward. Boundaries are available."; break; case ExperienceScale.World: scaleDescription = "The user is free to move about the world. Relies upon knowledge of the environment (Spatial Anchors and Spatial Mapping)."; break; } if (scaleDescription != string.Empty) { GUILayout.Space(6f); EditorGUILayout.HelpBox(scaleDescription, MessageType.Info); } } } // Camera Profile configuration EditorGUILayout.Space(); showCameraProperties = EditorGUILayout.Foldout(showCameraProperties, "Camera Settings", true); if (showCameraProperties) { using (new EditorGUI.IndentLevelScope()) { EditorGUILayout.PropertyField(enableCameraProfile); changed |= RenderProfile(cameraProfile); } } // Input System configuration EditorGUILayout.Space(); showInputProperties = EditorGUILayout.Foldout(showInputProperties, "Input System Settings", true); if (showInputProperties) { using (new EditorGUI.IndentLevelScope()) { EditorGUILayout.PropertyField(enableInputSystem); EditorGUILayout.PropertyField(inputSystemType); changed |= RenderProfile(inputSystemProfile); } } // Boundary System configuration EditorGUILayout.Space(); showBoundaryProperties = EditorGUILayout.Foldout(showBoundaryProperties, "Boundary System Settings", true); if (showBoundaryProperties) { using (new EditorGUI.IndentLevelScope()) { if (experienceScale != ExperienceScale.Room) { // Alert the user if the experience scale does not support boundary features. GUILayout.Space(6f); EditorGUILayout.HelpBox("Boundaries are only supported in Room scale experiences.", MessageType.Warning); GUILayout.Space(6f); } EditorGUILayout.PropertyField(enableBoundarySystem); EditorGUILayout.PropertyField(boundarySystemType); changed |= RenderProfile(boundaryVisualizationProfile); } } // Teleport System configuration EditorGUILayout.Space(); showTeleportProperties = EditorGUILayout.Foldout(showTeleportProperties, "Teleport System Settings", true); if (showTeleportProperties) { using (new EditorGUI.IndentLevelScope()) { EditorGUILayout.PropertyField(enableTeleportSystem); EditorGUILayout.PropertyField(teleportSystemType); } } // Spatial Awareness System configuration EditorGUILayout.Space(); showSpatialAwarenessProperties = EditorGUILayout.Foldout(showSpatialAwarenessProperties, "Spatial Awareness System Settings", true); if (showSpatialAwarenessProperties) { using (new EditorGUI.IndentLevelScope()) { EditorGUILayout.PropertyField(enableSpatialAwarenessSystem); EditorGUILayout.PropertyField(spatialAwarenessSystemType); EditorGUILayout.HelpBox("Spatial Awareness settings are configured per observer.", MessageType.Info); changed |= RenderProfile(spatialAwarenessSystemProfile); } } // Diagnostics System configuration EditorGUILayout.Space(); showDiagnosticProperties = EditorGUILayout.Foldout(showDiagnosticProperties, "Diagnostics System Settings", true); if (showDiagnosticProperties) { using (new EditorGUI.IndentLevelScope()) { EditorGUILayout.HelpBox("It is recommended to enable the Diagnostics system during development. Be sure to disable prior to building your shipping product.", MessageType.Warning); EditorGUILayout.PropertyField(enableDiagnosticsSystem); EditorGUILayout.PropertyField(diagnosticsSystemType); changed |= RenderProfile(diagnosticsSystemProfile); } } // Registered Services configuration EditorGUILayout.Space(); showRegisteredServiceProperties = EditorGUILayout.Foldout(showRegisteredServiceProperties, "Extension Services", true); if (showRegisteredServiceProperties) { using (new EditorGUI.IndentLevelScope()) { changed |= RenderProfile(registeredServiceProvidersProfile); } } if (!changed) { changed |= EditorGUI.EndChangeCheck(); } EditorGUIUtility.labelWidth = previousLabelWidth; serializedObject.ApplyModifiedProperties(); if (changed) { EditorApplication.delayCall += () => MixedRealityToolkit.Instance.ResetConfiguration(configurationProfile); } }
public override void OnInspectorGUI() { var configurationProfile = (MixedRealityToolkitConfigurationProfile)target; serializedObject.Update(); RenderMRTKLogo(); CheckEditorPlayMode(); if (!MixedRealityToolkit.IsInitialized) { EditorGUILayout.HelpBox("No Mixed Reality Toolkit found in scene.", MessageType.Warning); if (InspectorUIUtility.RenderIndentedButton("Add Mixed Reality Toolkit instance to scene")) { MixedRealityInspectorUtility.AddMixedRealityToolkitToScene(configurationProfile); } } if (!configurationProfile.IsCustomProfile) { EditorGUILayout.HelpBox("The Mixed Reality Toolkit's core SDK profiles can be used to get up and running quickly.\n\n" + "You can use the default profiles provided, copy and customize the default profiles, or create your own.", MessageType.Warning); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Copy & Customize")) { SerializedProperty targetProperty = null; UnityEngine.Object selectionTarget = null; // If we have an active MRTK instance, find its config profile serialized property if (MixedRealityToolkit.IsInitialized) { selectionTarget = MixedRealityToolkit.Instance; SerializedObject mixedRealityToolkitObject = new SerializedObject(MixedRealityToolkit.Instance); targetProperty = mixedRealityToolkitObject.FindProperty("activeProfile"); } MixedRealityProfileCloneWindow.OpenWindow(null, target as BaseMixedRealityProfile, targetProperty, selectionTarget); } if (MixedRealityToolkit.IsInitialized) { if (GUILayout.Button("Create new profiles")) { ScriptableObject profile = CreateInstance(nameof(MixedRealityToolkitConfigurationProfile)); var newProfile = profile.CreateAsset("Assets/MixedRealityToolkit.Generated/CustomProfiles") as MixedRealityToolkitConfigurationProfile; UnityEditor.Undo.RecordObject(MixedRealityToolkit.Instance, "Create new profiles"); MixedRealityToolkit.Instance.ActiveProfile = newProfile; Selection.activeObject = newProfile; } } EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField(string.Empty, GUI.skin.horizontalSlider); } bool isGUIEnabled = !IsProfileLock((BaseMixedRealityProfile)target) && GUI.enabled; GUI.enabled = isGUIEnabled; EditorGUI.BeginChangeCheck(); bool changed = false; // Experience configuration ExperienceScale experienceScale = (ExperienceScale)targetExperienceScale.intValue; EditorGUILayout.PropertyField(targetExperienceScale, TargetScaleContent); string scaleDescription = GetExperienceDescription(experienceScale); if (!string.IsNullOrEmpty(scaleDescription)) { EditorGUILayout.HelpBox(scaleDescription, MessageType.Info); EditorGUILayout.Space(); } changed |= EditorGUI.EndChangeCheck(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(EditorStyles.helpBox, GUILayout.Width(100)); GUI.enabled = true; // Force enable so we can view profile defaults int prefsSelectedTab = EditorPrefs.GetInt(SelectedTabPreferenceKey); SelectedProfileTab = GUILayout.SelectionGrid(prefsSelectedTab, ProfileTabTitles, 1, EditorStyles.boldLabel, GUILayout.MaxWidth(125)); if (SelectedProfileTab != prefsSelectedTab) { EditorPrefs.SetInt(SelectedTabPreferenceKey, SelectedProfileTab); } GUI.enabled = isGUIEnabled; EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(EditorStyles.helpBox); using (new EditorGUI.IndentLevelScope()) { changed |= RenderProfileFuncs[SelectedProfileTab](); } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); serializedObject.ApplyModifiedProperties(); GUI.enabled = true; if (changed && MixedRealityToolkit.IsInitialized) { EditorApplication.delayCall += () => MixedRealityToolkit.Instance.ResetConfiguration(configurationProfile); } }
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); }
/// <summary> /// Draws a dropdown with all available profiles of types contained in the array profilyTypes. /// </summary> /// <returns>True if property was changed.</returns> public static bool DrawProfileDropDownList(SerializedProperty property, BaseMixedRealityProfile profile, Object oldProfileObject, Type[] profileTypes, bool requiresProfile, bool showAddButton) { bool changed = false; using (new EditorGUILayout.HorizontalScope()) { List<ScriptableObject> profileInstanceList = new List<ScriptableObject>(); List<GUIContent> profileContentList = new List<GUIContent>(); // Pull profile instances and profile content from cache for(int i = 0; i < profileTypes.Length; i++) { Type profileType = profileTypes[i]; profileInstanceList.AddRange(MixedRealityProfileUtility.GetProfilesOfType(profileType)); profileContentList.AddRange(MixedRealityProfileUtility.GetProfilePopupOptionsByType(profileType)); } int dropdownOffset = 0; if (!requiresProfile || profileInstanceList.Count == 0) { profileContentList.Insert(0, new GUIContent("(None)")); dropdownOffset = 1; } ScriptableObject[] profileInstances = profileInstanceList.ToArray(); GUIContent[] profileContent = profileContentList.ToArray(); int selectedIndex = 0; // Find our selected index for (int i = 0; i < profileInstances.Length; i++) { if (profileInstances[i] == oldProfileObject) { // If a profile is required, then the selected index is the same as the profile instance index, otherwise it is offset by the dropdownOffset // due to the pre-existing (None) option selectedIndex = i + dropdownOffset; break; } } int newIndex = EditorGUILayout.Popup( new GUIContent(oldProfileObject != null ? "" : property.displayName), selectedIndex, profileContent, GUILayout.ExpandWidth(true)); int profileInstanceIndex = newIndex - dropdownOffset; property.objectReferenceValue = (profileInstanceIndex >= 0) ? profileInstances[profileInstanceIndex] : null; changed = property.objectReferenceValue != oldProfileObject; // Draw a button that finds the profile in the project window if (property.objectReferenceValue != null) { // The view asset button should always be enabled. using (new GUIEnabledWrapper()) { if (GUILayout.Button("View Asset", EditorStyles.miniButton, GUILayout.Width(80))) { EditorGUIUtility.PingObject(property.objectReferenceValue); } } } // Draw the clone button if (property.objectReferenceValue == null) { if (showAddButton && MixedRealityProfileUtility.IsConcreteProfileType(Selection.activeObject.GetType())) { if (GUILayout.Button(NewProfileContent, EditorStyles.miniButton, GUILayout.Width(20f))) { ScriptableObject instance = ScriptableObject.CreateInstance(Selection.activeObject.GetType()); 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); if (GUILayout.Button(new GUIContent("Clone", "Replace with a copy of the default profile."), EditorStyles.miniButton, GUILayout.Width(45f))) { MixedRealityProfileCloneWindow.OpenWindow(profile, renderedProfile, property); } } } return changed; }
/// <summary> /// Draws a dropdown with all available profiles of profilyType. /// </summary> /// <returns>True if property was changed.</returns> public static bool DrawProfileDropDownList(SerializedProperty property, BaseMixedRealityProfile profile, Object oldProfileObject, Type profileType, bool showAddButton) { bool changed = false; using (new EditorGUILayout.HorizontalScope()) { // Pull profile instances and profile content from cache ScriptableObject[] profileInstances = MixedRealityProfileUtility.GetProfilesOfType(profileType); GUIContent[] profileContent = MixedRealityProfileUtility.GetProfilePopupOptionsByType(profileType); // Set our selected index to our '(None)' option by default int selectedIndex = 0; // Find our selected index for (int i = 0; i < profileInstances.Length; i++) { if (profileInstances[i] == oldProfileObject) { // Our profile content has a '(None)' option at the start selectedIndex = i + 1; break; } } int newIndex = EditorGUILayout.Popup( new GUIContent(oldProfileObject != null ? "" : property.displayName), selectedIndex, profileContent, GUILayout.ExpandWidth(true)); property.objectReferenceValue = (newIndex > 0) ? profileInstances[newIndex - 1] : null; changed = property.objectReferenceValue != oldProfileObject; // Draw a button that finds the profile in the project window if (property.objectReferenceValue != null) { // The view asset button should always be enabled. using (new GUIEnabledWrapper()) { if (GUILayout.Button("View Asset", EditorStyles.miniButton, GUILayout.Width(80))) { EditorGUIUtility.PingObject(property.objectReferenceValue); } } } // Draw the clone button if (property.objectReferenceValue == null) { if (showAddButton && MixedRealityProfileUtility.IsConcreteProfileType(profileType)) { if (GUILayout.Button(NewProfileContent, EditorStyles.miniButton, GUILayout.Width(20f))) { ScriptableObject instance = ScriptableObject.CreateInstance(profileType); 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); if (GUILayout.Button(new GUIContent("Clone", "Replace with a copy of the default profile."), EditorStyles.miniButton, GUILayout.Width(45f))) { MixedRealityProfileCloneWindow.OpenWindow(profile, renderedProfile, property); } } } return(changed); }