RenderStreamingProjectSettingsProvider.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using UnityEditor;
  6. using UnityEditor.UIElements;
  7. using UnityEngine;
  8. using UnityEngine.UIElements;
  9. namespace Unity.RenderStreaming.Editor
  10. {
  11. internal class RenderStreamingProjectSettingsProvider : SettingsProvider
  12. {
  13. internal VisualElement rootVisualElement { get; private set; }
  14. private bool isDefaultSettings => AssetDatabase.GetAssetPath(RenderStreaming.Settings) ==
  15. RenderStreaming.DefaultRenderStreamingSettingsPath;
  16. private bool noSettingsInAssets => availableRenderStreamingSettingsAssets.Length == 0
  17. || availableRenderStreamingSettingsAssets.All(x => x == RenderStreaming.DefaultRenderStreamingSettingsPath);
  18. private string[] availableRenderStreamingSettingsAssets;
  19. private int currentSelectedSettingsAsset;
  20. private RenderStreamingSettings settings;
  21. const string kSettingsPath = "Project/Render Streaming";
  22. const string kTemplatePath = "Packages/com.unity.renderstreaming/Editor/UXML/RenderStreamingProjectSettings.uxml";
  23. const string kStylePath = "Packages/com.unity.renderstreaming/Editor/Styles/RenderStreamingProjectSettings.uss";
  24. [SettingsProvider]
  25. public static SettingsProvider CreateProvider()
  26. {
  27. return new RenderStreamingProjectSettingsProvider(kSettingsPath, SettingsScope.Project, new List<string>()
  28. {
  29. L10n.Tr("experimental"),
  30. L10n.Tr("streaming"),
  31. L10n.Tr("webrtc"),
  32. L10n.Tr("video"),
  33. L10n.Tr("audio"),
  34. });
  35. }
  36. public override void OnActivate(string searchContext, VisualElement rootElement)
  37. {
  38. var styleSheet = EditorGUIUtility.Load(kStylePath) as StyleSheet;
  39. rootVisualElement = new ScrollView();
  40. rootVisualElement.StretchToParentSize();
  41. rootVisualElement.styleSheets.Add(styleSheet);
  42. rootElement.Add(rootVisualElement);
  43. var template = EditorGUIUtility.Load(kTemplatePath) as VisualTreeAsset;
  44. VisualElement newVisualElement = new VisualElement();
  45. template.CloneTree(newVisualElement);
  46. rootVisualElement.Add(newVisualElement);
  47. settings = RenderStreaming.Settings;
  48. availableRenderStreamingSettingsAssets = FindRenderStreamingSettingsPathInProject();
  49. var selectorContainer = rootVisualElement.Q<VisualElement>("renderStreamingSettingsSelector");
  50. var defaultIndex = ArrayHelpers.IndexOf(availableRenderStreamingSettingsAssets, AssetDatabase.GetAssetPath(settings));
  51. var choices = availableRenderStreamingSettingsAssets.ToList();
  52. var selectPopup = new PopupField<string>(label: label, choices: choices, defaultIndex: defaultIndex)
  53. {
  54. name = "renderStreamingSettingsSelectPopup"
  55. };
  56. selectPopup.RegisterValueChangedCallback(evt =>
  57. {
  58. currentSelectedSettingsAsset = selectPopup.index;
  59. var newSettings =
  60. AssetDatabase.LoadAssetAtPath<RenderStreamingSettings>(availableRenderStreamingSettingsAssets[currentSelectedSettingsAsset]);
  61. if (newSettings == settings)
  62. {
  63. return;
  64. }
  65. RenderStreaming.Settings = newSettings;
  66. });
  67. selectorContainer.Add(selectPopup);
  68. var createSettingsButton = new Button {text = "Create New Settings Asset"};
  69. createSettingsButton.clicked += () =>
  70. {
  71. CreateNewSettingsAsset();
  72. Repaint();
  73. };
  74. selectorContainer.Add(createSettingsButton);
  75. var createAssetHelpBox = new HelpBox("Settings for the Render Streaming are not stored in an asset. Click the button above to create a settings asset you can edit.", HelpBoxMessageType.Info)
  76. {
  77. style = {display = noSettingsInAssets ? DisplayStyle.Flex : DisplayStyle.None}
  78. };
  79. selectorContainer.Add(createAssetHelpBox);
  80. ShowRenderStreamingSettingsProperty();
  81. // Disable UI when running in Playmode
  82. EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
  83. if(EditorApplication.isPlaying)
  84. rootVisualElement.SetEnabled(false);
  85. }
  86. public override void OnInspectorUpdate()
  87. {
  88. if (RenderStreaming.Settings == settings && settings != null)
  89. {
  90. return;
  91. }
  92. settings = RenderStreaming.Settings;
  93. var index = ArrayHelpers.IndexOf(availableRenderStreamingSettingsAssets, AssetDatabase.GetAssetPath(settings));
  94. rootVisualElement.Q<PopupField<string>>("renderStreamingSettingsSelectPopup").index = index;
  95. ShowRenderStreamingSettingsProperty();
  96. }
  97. private static string[] FindRenderStreamingSettingsPathInProject()
  98. {
  99. var guids = AssetDatabase.FindAssets("t:RenderStreamingSettings");
  100. return guids.Select(AssetDatabase.GUIDToAssetPath)
  101. .Where(path => !path.StartsWith("Packages") || path.StartsWith(RenderStreaming.DefaultRenderStreamingSettingsPath))
  102. .ToArray();
  103. }
  104. private static void CreateNewSettingsAsset()
  105. {
  106. // Query for file name.
  107. var projectName = PlayerSettings.productName;
  108. var path = EditorUtility.SaveFilePanel("Create Render Streaming Settings File", "Assets",
  109. projectName, "asset");
  110. if (string.IsNullOrEmpty(path))
  111. return;
  112. // Make sure the path is in the Assets/ folder.
  113. var dataPath = Application.dataPath + "/";
  114. if (!path.StartsWith(dataPath, StringComparison.CurrentCultureIgnoreCase))
  115. {
  116. Debug.LogError($"Render Streaming settings must be stored in Assets folder of the project (got: '{path}')");
  117. return;
  118. }
  119. // Make sure it ends with .asset.
  120. var extension = Path.GetExtension(path);
  121. if (string.Compare(extension, ".asset", StringComparison.InvariantCultureIgnoreCase) != 0)
  122. path += ".asset";
  123. // Create settings file.
  124. var relativePath = "Assets/" + path.Substring(dataPath.Length);
  125. CreateNewSettingsAsset(relativePath);
  126. }
  127. private static void CreateNewSettingsAsset(string relativePath)
  128. {
  129. var settings = ScriptableObject.CreateInstance<RenderStreamingSettings>();
  130. AssetDatabase.CreateAsset(settings, relativePath);
  131. EditorGUIUtility.PingObject(settings);
  132. RenderStreaming.Settings = settings;
  133. }
  134. private void OnPlayModeStateChanged(PlayModeStateChange e)
  135. {
  136. switch (e)
  137. {
  138. case PlayModeStateChange.EnteredPlayMode:
  139. rootVisualElement.SetEnabled(false);
  140. break;
  141. case PlayModeStateChange.ExitingPlayMode:
  142. rootVisualElement.SetEnabled(true);
  143. break;
  144. }
  145. }
  146. private void ShowRenderStreamingSettingsProperty()
  147. {
  148. var settingsPropertyContainer = rootVisualElement.Q("settingsPropertyContainer");
  149. settingsPropertyContainer.Clear();
  150. var editor = UnityEditor.Editor.CreateEditor(settings);
  151. var inspectorGUI = editor.CreateInspectorGUI();
  152. inspectorGUI.SetEnabled(!isDefaultSettings);
  153. inspectorGUI.Bind(editor.serializedObject);
  154. if (!noSettingsInAssets && isDefaultSettings)
  155. {
  156. settingsPropertyContainer.Add(new HelpBox("This is package default settings. Please select other settings asset you can edit.", HelpBoxMessageType.Info));
  157. }
  158. settingsPropertyContainer.Add(inspectorGUI);
  159. }
  160. public RenderStreamingProjectSettingsProvider(string path, SettingsScope scopes, IEnumerable<string> keywords = null)
  161. : base(path, scopes, keywords)
  162. {
  163. }
  164. }
  165. }