using Module.Inspector.Editor.Utilities; using UnityEditor; using UnityEngine; namespace Module.Inspector.Editor { [CustomPropertyDrawer(typeof(FilePathAttribute))] internal sealed class FilePathAttributeDrawer : DrawerPropertyDrawer { public override bool Draw(Rect position, DrawerPropertyAttribute attribute, SerializedProperty property, GUIContent label, EditorPropertyUtility.Result result) { if (property.propertyType != SerializedPropertyType.String) return false; var att = (FilePathAttribute)attribute; EditorGUI.BeginProperty(position, label, property); { const float WIDTH = 80; var rect0 = new Rect(position.x, position.y, position.width - WIDTH, position.height); var rect1 = new Rect(rect0.xMax, position.y, WIDTH, position.height); string temp = EditorGUI.TextField(rect0, label, property.stringValue); if (!temp.Equals(property.stringValue)) property.stringValue = temp; if (GUI.Button(rect1, "Find")) { string folderPath = GetInitialFolderPath(att.pathType); string path = EditorUtility.OpenFilePanel("File", folderPath, att.extension); if (!string.IsNullOrEmpty(path)) path = TransformAbsolutePathTo(path, att.pathType); if (!string.IsNullOrEmpty(path)) { property.stringValue = path; property.serializedObject.ApplyModifiedProperties(); } } } EditorGUI.EndProperty(); return true; } private static string GetInitialFolderPath(EFilePathType pathType) { if (pathType == EFilePathType.RelativeToStreamingFolder) return "Assets/StreamingAssets/"; return "Assets/"; } private string TransformAbsolutePathTo(string absolutePath, EFilePathType pathType) { absolutePath = absolutePath.Replace('\\', '/'); var dataPath = Application.dataPath.Replace('\\', '/'); if (pathType == EFilePathType.RelativeToProjectFolder) { if (absolutePath.StartsWith(dataPath)) return absolutePath.Remove(0, dataPath.Length - 6); Debug.LogWarning("Path didn't include 'Assets'-folder"); return string.Empty; } if (pathType == EFilePathType.RelativeToStreamingFolder) { if (absolutePath.StartsWith($"{dataPath}/StreamingAssets")) return absolutePath.Remove(0, dataPath.Length + 17); Debug.LogWarning("Path didn't include 'StreamingAssets'-folder"); return string.Empty; } return absolutePath; } public override string GetErrorMessage(SerializedProperty property) { return "Only supports strings"; } } }