#if UNITY_EDITOR using System; using System.IO; using UnityEditor; using UnityEngine.UIElements; namespace UnityEngine.InputSystem.Editor { internal static class InputAssetEditorUtils { /// /// Represents a dialog result. /// internal enum DialogResult { /// /// The dialog was closed with an invalid path. /// InvalidPath, /// /// The dialog was cancelled by the user and the path is invalid. /// Cancelled, /// /// The dialog was accepted by the user and the associated path is valid. /// Valid } internal struct PromptResult { public PromptResult(DialogResult result, string path) { this.result = result; this.relativePath = path; } public readonly DialogResult result; public readonly string relativePath; } internal static string MakeProjectFileName(string projectNameSuffixNoExtension) { return PlayerSettings.productName + "." + projectNameSuffixNoExtension; } internal static PromptResult PromptUserForAsset(string friendlyName, string suggestedAssetFilePathWithoutExtension, string assetFileExtension) { // Prompt user for a file name. var fullAssetFileExtension = "." + assetFileExtension; var path = EditorUtility.SaveFilePanel( title: $"Create {friendlyName} File", directory: "Assets", defaultName: suggestedAssetFilePathWithoutExtension + "." + assetFileExtension, extension: assetFileExtension); if (string.IsNullOrEmpty(path)) return new PromptResult(DialogResult.Cancelled, null); // Make sure the path is in the Assets/ folder. path = path.Replace("\\", "/"); // Make sure we only get '/' separators. var dataPath = Application.dataPath + "/"; if (!path.StartsWith(dataPath, StringComparison.CurrentCultureIgnoreCase)) { Debug.LogError($"{friendlyName} must be stored in Assets folder of the project (got: '{path}')"); return new PromptResult(DialogResult.InvalidPath, null); } // Make sure path ends with expected extension var extension = Path.GetExtension(path); if (string.Compare(extension, fullAssetFileExtension, StringComparison.InvariantCultureIgnoreCase) != 0) path += fullAssetFileExtension; return new PromptResult(DialogResult.Valid, "Assets/" + path.Substring(dataPath.Length)); } internal static T CreateAsset(T asset, string relativePath) where T : ScriptableObject { AssetDatabase.CreateAsset(asset, relativePath); EditorGUIUtility.PingObject(asset); return asset; } public static VisualElement CreateMakeActiveGui(Func getCurrent, T target, string targetName, string entity, Action apply, Action subscribeToChanges, Action unsubscribeFromChanges, bool allowAssignActive = true) where T : ScriptableObject { var container = new VisualElement(); void Refresh() => PopulateMakeActiveGui(container, getCurrent(), target, entity, apply, allowAssignActive); Refresh(); // Subscribe for as long as the element is part of a panel, matching the pattern used in InputParameterEditor. container.RegisterCallback(_ => subscribeToChanges(Refresh)); container.RegisterCallback(_ => unsubscribeFromChanges(Refresh)); return container; } private static void PopulateMakeActiveGui(VisualElement container, T current, T target, string entity, Action apply, bool allowAssignActive) where T : ScriptableObject { container.Clear(); if (current == target) { container.Add(new HelpBox($"These actions are assigned as the {entity}.", HelpBoxMessageType.Info)); return; } string currentlyActiveAssetsPath = null; if (current != null) currentlyActiveAssetsPath = AssetDatabase.GetAssetPath(current); if (!string.IsNullOrEmpty(currentlyActiveAssetsPath)) currentlyActiveAssetsPath = $" The actions currently assigned as the {entity} are: {currentlyActiveAssetsPath}. "; container.Add(new HelpBox( $"These actions are not assigned as the {entity} for the Input System. {currentlyActiveAssetsPath ?? ""}", HelpBoxMessageType.Warning)); var assignButton = new Button(() => { apply(target); PopulateMakeActiveGui(container, target, target, entity, apply, allowAssignActive); }) { text = $"Assign as the {entity}", style = { minHeight = 30, whiteSpace = WhiteSpace.Normal } }; assignButton.SetEnabled(allowAssignActive); container.Add(assignButton); } public static bool IsValidFileExtension(string path) { return path != null && path.EndsWith("." + InputActionAsset.Extension, StringComparison.InvariantCultureIgnoreCase); } } } #endif // UNITY_EDITOR