| using System; |
| using System.Linq; |
| using System.IO; |
| using System.Runtime.CompilerServices; |
| using UnityEngine; |
| using UnityEditor; |
| using UnityEngine.UIElements; |
|
|
| [assembly: InternalsVisibleTo("Unity.ML-Agents.DevTests.Editor")] |
| namespace Unity.MLAgents.Editor |
| { |
| internal class MLAgentsSettingsProvider : SettingsProvider, IDisposable |
| { |
| const string k_SettingsPath = "Project/ML-Agents"; |
| private static MLAgentsSettingsProvider s_Instance; |
| private string[] m_AvailableSettingsAssets; |
| private int m_CurrentSelectedSettingsAsset; |
| private SerializedObject m_SettingsObject; |
| [SerializeField] |
| private MLAgentsSettings m_Settings; |
|
|
|
|
| private MLAgentsSettingsProvider(string path, SettingsScope scope = SettingsScope.Project) |
| : base(path, scope) |
| { |
| s_Instance = this; |
| } |
|
|
| [SettingsProvider] |
| public static SettingsProvider CreateMLAgentsSettingsProvider() |
| { |
| return new MLAgentsSettingsProvider(k_SettingsPath, SettingsScope.Project); |
| } |
|
|
| public override void OnActivate(string searchContext, VisualElement rootElement) |
| { |
| base.OnActivate(searchContext, rootElement); |
| MLAgentsSettingsManager.OnSettingsChange += Reinitialize; |
| } |
|
|
| public override void OnDeactivate() |
| { |
| base.OnDeactivate(); |
| MLAgentsSettingsManager.OnSettingsChange -= Reinitialize; |
| } |
|
|
| public void Dispose() |
| { |
| m_SettingsObject?.Dispose(); |
| } |
|
|
| public override void OnTitleBarGUI() |
| { |
| if (EditorGUILayout.DropdownButton(EditorGUIUtility.IconContent("_Popup"), FocusType.Passive, EditorStyles.label)) |
| { |
| var menu = new GenericMenu(); |
| for (var i = 0; i < m_AvailableSettingsAssets.Length; i++) |
| { |
| menu.AddItem(ExtractDisplayName(m_AvailableSettingsAssets[i]), m_CurrentSelectedSettingsAsset == i, (path) => |
| { |
| MLAgentsSettingsManager.Settings = AssetDatabase.LoadAssetAtPath<MLAgentsSettings>((string)path); |
| }, m_AvailableSettingsAssets[i]); |
| } |
| menu.AddSeparator(""); |
| menu.AddItem(new GUIContent("New Settings Asset…"), false, CreateNewSettingsAsset); |
| menu.ShowAsContext(); |
| Event.current.Use(); |
| } |
| } |
|
|
| private GUIContent ExtractDisplayName(string name) |
| { |
| if (name.StartsWith("Assets/")) |
| name = name.Substring("Assets/".Length); |
| if (name.EndsWith(".asset")) |
| name = name.Substring(0, name.Length - ".asset".Length); |
| if (name.EndsWith(".mlagents.settings")) |
| name = name.Substring(0, name.Length - ".mlagents.settings".Length); |
|
|
| |
| return new GUIContent(name.Replace("/", "\u29f8")); |
| } |
|
|
| private void CreateNewSettingsAsset() |
| { |
| |
| var projectName = PlayerSettings.productName; |
| var path = EditorUtility.SaveFilePanel("Create ML-Agents Settings File", "Assets", |
| projectName + ".mlagents.settings", "asset"); |
| if (string.IsNullOrEmpty(path)) |
| { |
| return; |
| } |
|
|
| path = path.Replace("\\", "/"); |
| var assetPath = Application.dataPath + "/"; |
| if (!path.StartsWith(assetPath, StringComparison.CurrentCultureIgnoreCase)) |
| { |
| Debug.LogError(string.Format( |
| "Settings must be stored in Assets folder of the project (got: '{0}')", path)); |
| return; |
| } |
|
|
| var extension = Path.GetExtension(path); |
| if (string.Compare(extension, ".asset", StringComparison.InvariantCultureIgnoreCase) != 0) |
| { |
| path += ".asset"; |
| } |
| var relativePath = "Assets/" + path.Substring(assetPath.Length); |
| CreateNewSettingsAsset(relativePath); |
| } |
|
|
| private static void CreateNewSettingsAsset(string relativePath) |
| { |
| var settings = ScriptableObject.CreateInstance<MLAgentsSettings>(); |
| AssetDatabase.CreateAsset(settings, relativePath); |
| EditorGUIUtility.PingObject(settings); |
| |
| |
| MLAgentsSettingsManager.Settings = settings; |
| } |
|
|
| public override void OnGUI(string searchContext) |
| { |
| if (m_Settings == null) |
| { |
| InitializeWithCurrentSettings(); |
| } |
|
|
| if (m_AvailableSettingsAssets.Length == 0) |
| { |
| EditorGUILayout.HelpBox( |
| "Click the button below to create a settings asset you can edit.", |
| MessageType.Info); |
| if (GUILayout.Button("Create settings asset", GUILayout.Height(30))) |
| CreateNewSettingsAsset(); |
| GUILayout.Space(20); |
| } |
|
|
| using (new EditorGUI.DisabledScope(m_AvailableSettingsAssets.Length == 0)) |
| { |
| EditorGUI.BeginChangeCheck(); |
| EditorGUILayout.LabelField("Trainer Settings", EditorStyles.boldLabel); |
| EditorGUI.indentLevel++; |
| EditorGUILayout.PropertyField(m_SettingsObject.FindProperty("m_ConnectTrainer"), new GUIContent("Connect to Trainer")); |
| EditorGUILayout.PropertyField(m_SettingsObject.FindProperty("m_EditorPort"), new GUIContent("Editor Training Port")); |
| EditorGUI.indentLevel--; |
| if (EditorGUI.EndChangeCheck()) |
| m_SettingsObject.ApplyModifiedProperties(); |
| } |
| } |
|
|
| internal void InitializeWithCurrentSettings() |
| { |
| m_AvailableSettingsAssets = FindSettingsInProject(); |
|
|
| m_Settings = MLAgentsSettingsManager.Settings; |
| var currentSettingsPath = AssetDatabase.GetAssetPath(m_Settings); |
| if (string.IsNullOrEmpty(currentSettingsPath)) |
| { |
| if (m_AvailableSettingsAssets.Length > 0) |
| { |
| m_CurrentSelectedSettingsAsset = 0; |
| m_Settings = AssetDatabase.LoadAssetAtPath<MLAgentsSettings>(m_AvailableSettingsAssets[0]); |
| MLAgentsSettingsManager.Settings = m_Settings; |
| } |
| } |
| else |
| { |
| var settingsList = m_AvailableSettingsAssets.ToList(); |
| m_CurrentSelectedSettingsAsset = settingsList.IndexOf(currentSettingsPath); |
|
|
| EditorBuildSettings.AddConfigObject(MLAgentsSettingsManager.EditorBuildSettingsConfigKey, m_Settings, true); |
| } |
|
|
| m_SettingsObject = new SerializedObject(m_Settings); |
| } |
|
|
| private static string[] FindSettingsInProject() |
| { |
| var guids = AssetDatabase.FindAssets("t:MLAgentsSettings"); |
| return guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid)).ToArray(); |
| } |
|
|
| private void Reinitialize() |
| { |
| if (m_Settings != null && MLAgentsSettingsManager.Settings != m_Settings) |
| { |
| InitializeWithCurrentSettings(); |
| } |
| Repaint(); |
| } |
| } |
| } |
|
|