using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; using UnityEngine.Rendering; namespace FlatKit { [CustomEditor(typeof(FlatKitReadme))] public class ReadmeEditor : Editor { private static readonly string AssetName = "Flat Kit"; private static readonly GUID UnityPackageUrpGuid = new GUID("41e59f562b69648719f2424c438758f3"); private static readonly GUID UnityPackageBuiltInGuid = new GUID("f4227764308e84f89a765fbf315e2945"); // 2b85f0b7-3248-4e28-8900-a861e01241ba // 95b02117-de66-49f0-91e7-cc5f4291cf90 private FlatKitReadme _readme; private bool _showingVersionMessage; private string _versionLatest; private bool _showingClearCacheMessage; private bool _cacheClearedSuccessfully; private void OnEnable() { _readme = serializedObject.targetObject as FlatKitReadme; if (_readme == null) { Debug.LogError($"[{AssetName}] Readme error."); return; } _readme.Refresh(); _showingVersionMessage = false; _showingClearCacheMessage = false; _versionLatest = null; AssetDatabase.importPackageStarted += OnImportPackageStarted; AssetDatabase.importPackageCompleted += OnImportPackageCompleted; AssetDatabase.importPackageFailed += OnImportPackageFailed; AssetDatabase.importPackageCancelled += OnImportPackageCancelled; } private void OnDisable() { AssetDatabase.importPackageStarted -= OnImportPackageStarted; AssetDatabase.importPackageCompleted -= OnImportPackageCompleted; AssetDatabase.importPackageFailed -= OnImportPackageFailed; AssetDatabase.importPackageCancelled -= OnImportPackageCancelled; } public override void OnInspectorGUI() { { EditorGUILayout.LabelField(AssetName, EditorStyles.boldLabel); DrawUILine(Color.gray, 1, 0); EditorGUILayout.LabelField($"Version {_readme.FlatKitVersion}", EditorStyles.miniLabel); EditorGUILayout.Separator(); } if (GUILayout.Button("Documentation")) { OpenDocumentation(); } { if (_showingVersionMessage) { if (_versionLatest == null) { EditorGUILayout.HelpBox($"Checking the latest version...", MessageType.None); } else { EditorGUILayout.Space(20); var local = Version.Parse(_readme.FlatKitVersion); var remote = Version.Parse(_versionLatest); if (local >= remote) { EditorGUILayout.HelpBox($"You have the latest version! {_readme.FlatKitVersion}.", MessageType.Info); } else { EditorGUILayout.HelpBox( $"Update needed. " + $"The latest version is {_versionLatest}, but you have {_readme.FlatKitVersion}.", MessageType.Warning); #if !UNITY_2020_3_OR_NEWER EditorGUILayout.HelpBox( $"Please update Unity to 2020.3 or newer to get the latest version of Flat Kit.", MessageType.Error); #endif } } } if (GUILayout.Button("Check for updates")) { _showingVersionMessage = true; _versionLatest = null; CheckVersion(); } if (_showingVersionMessage) { EditorGUILayout.Space(20); } } { GUILayout.BeginHorizontal(); if (GUILayout.Button("Open support ticket")) { OpenSupportTicket(); } if (GUILayout.Button("Copy debug info")) { CopyDebugInfoToClipboard(); } GUILayout.EndHorizontal(); } { if (!_readme.FlatKitInstalled) { EditorGUILayout.Separator(); DrawUILine(Color.yellow, 1, 0); EditorGUILayout.HelpBox( $"Before using {AssetName} you need to unpack it depending on your project's Render Pipeline.", MessageType.Warning); GUILayout.BeginHorizontal(); EditorGUILayout.LabelField($"Unpack {AssetName} for", EditorStyles.label); if (GUILayout.Button("URP")) { UnpackFlatKitUrp(); } if (GUILayout.Button("Built-in RP")) { UnpackFlatKitBuiltInRP(); } GUILayout.EndHorizontal(); DrawUILine(Color.yellow, 1, 0); return; } } { if (!string.IsNullOrEmpty(_readme.PackageManagerError)) { EditorGUILayout.Separator(); DrawUILine(Color.yellow, 1, 0); EditorGUILayout.HelpBox($"Package Manager error: {_readme.PackageManagerError}", MessageType.Warning); DrawUILine(Color.yellow, 1, 0); } } { DrawUILine(Color.gray, 1, 20); EditorGUILayout.LabelField("Package Manager", EditorStyles.label); if (GUILayout.Button("Clear cache")) { ClearPackageCache(); } if (_showingClearCacheMessage) { if (_cacheClearedSuccessfully) { EditorGUILayout.HelpBox( $"Successfully removed cached packages. \n" + $"Please re-download {AssetName} in the Package Manager.", MessageType.Info); } else { EditorGUILayout.HelpBox($"Could not find or clear package cache.", MessageType.Warning); } } EditorGUILayout.Separator(); } DrawColorSpaceCheck(); { DrawUILine(Color.gray, 1, 20); GUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Debug info", EditorStyles.miniBoldLabel); GUILayout.BeginVertical(); if (GUILayout.Button("Copy", EditorStyles.miniButtonLeft)) { CopyDebugInfoToClipboard(); } if (EditorGUIUtility.systemCopyBuffer == GetDebugInfoString()) { EditorGUILayout.LabelField("Copied!", EditorStyles.miniLabel); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); var debugInfo = GetDebugInfo(); var style = new GUIStyle(EditorStyles.miniLabel) {wordWrap = true}; foreach (var s in debugInfo) { EditorGUILayout.LabelField($" " + s, style); } EditorGUILayout.Separator(); } } private List GetDebugInfo() { var renderPipelineAsset = GraphicsSettings.currentRenderPipeline; if (renderPipelineAsset == null) { renderPipelineAsset = GraphicsSettings.defaultRenderPipeline; } var rpAssetName = renderPipelineAsset == null ? "N/A" : renderPipelineAsset.name; var renderingPath = "Unknown"; if (Shader.IsKeywordEnabled("_FORWARD_PLUS")) { renderingPath = "Forward+"; } var info = new List { $"{AssetName} version {_readme.FlatKitVersion}", $"Unity {_readme.UnityVersion}", $"Dev platform: {Application.platform}", $"Target platform: {EditorUserBuildSettings.activeBuildTarget}", $"URP installed: {_readme.UrpInstalled}, version {_readme.UrpVersionInstalled}", $"Render pipeline: {Shader.globalRenderPipeline}", $"Render pipeline asset: {rpAssetName}", $"Rendering path: {renderingPath}", $"Color space: {PlayerSettings.colorSpace}" }; var qualityConfig = QualitySettings.renderPipeline == null ? "N/A" : QualitySettings.renderPipeline.name; info.Add($"Quality config: {qualityConfig}"); var graphicsConfig = GraphicsSettings.currentRenderPipeline == null ? "N/A" : GraphicsSettings.currentRenderPipeline.name; info.Add($"Graphics config: {graphicsConfig}"); return info; } private string GetDebugInfoString() { var info = GetDebugInfo(); { var keywords = new List(); foreach (var keyword in Shader.enabledGlobalKeywords) { if (Shader.IsKeywordEnabled(keyword)) { keywords.Add(keyword.name); } } var keywordsInfo = "Enabled global keywords: " + string.Join(", ", keywords); info.Add(keywordsInfo); } return string.Join("\n", info); } private void CopyDebugInfoToClipboard() { EditorGUIUtility.systemCopyBuffer = GetDebugInfoString(); } private void ClearPackageCache() { string path = string.Empty; if (Application.platform == RuntimePlatform.OSXEditor) { path = "~/Library/Unity/Asset Store-5.x/Dustyroom/"; } if (Application.platform == RuntimePlatform.LinuxEditor) { path = "~/.local/share/unity3d/Asset Store-5.x/Dustyroom/"; } if (Application.platform == RuntimePlatform.WindowsEditor) { // This wouldn't understand %APPDATA%. path = Application.persistentDataPath.Substring(0, Application.persistentDataPath.IndexOf("AppData", StringComparison.Ordinal)) + "/AppData/Roaming/Unity/Asset Store-5.x/Dustyroom"; } if (path == string.Empty) return; _cacheClearedSuccessfully |= FileUtil.DeleteFileOrDirectory(path); _showingClearCacheMessage = true; } private void UnpackFlatKitUrp() { string path = AssetDatabase.GUIDToAssetPath(UnityPackageUrpGuid.ToString()); if (path == null) { Debug.LogError($"[{AssetName}] Could not find the URP package."); } else { AssetDatabase.ImportPackage(path, false); } } private void UnpackFlatKitBuiltInRP() { string path = AssetDatabase.GUIDToAssetPath(UnityPackageBuiltInGuid.ToString()); if (path == null) { Debug.LogError($"[{AssetName}] Could not find the Built-in RP package."); } else { AssetDatabase.ImportPackage(path, false); } } private void OnImportPackageStarted(string packageName) { } private void OnImportPackageCompleted(string packageName) { _readme.Refresh(); Repaint(); EditorUtility.SetDirty(this); } private void OnImportPackageFailed(string packageName, string errorMessage) { Debug.LogError($"[{AssetName}] Failed to unpack {packageName}: {errorMessage}."); } private void OnImportPackageCancelled(string packageName) { Debug.LogError($"[{AssetName}] Cancelled unpacking {packageName}."); } private void DrawColorSpaceCheck() { if (PlayerSettings.colorSpace != ColorSpace.Linear) { DrawUILine(Color.gray, 1, 20); EditorGUILayout.HelpBox( $"{AssetName} demo scenes were created for the Linear color space, but your project is " + $"using {PlayerSettings.colorSpace}.\nThis may result in the demo scenes appearing slightly " + $"different compared to the Asset Store screenshots.\nOptionally, you may switch the color space " + $"using the button below.", MessageType.Warning); if (GUILayout.Button("Switch player settings to Linear color space")) { PlayerSettings.colorSpace = ColorSpace.Linear; } } } private void CheckVersion() { NetworkManager.GetVersion(version => { _versionLatest = version; }); } private void OpenSupportTicket() { Application.OpenURL("https://github.com/Dustyroom/flat-kit-doc/issues/new/choose"); } private void OpenDocumentation() { Application.OpenURL("https://flatkit.dustyroom.com"); } private static void DrawUILine(Color color, int thickness = 2, int padding = 10) { Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness)); r.height = thickness; r.y += padding / 2f; r.x -= 2; EditorGUI.DrawRect(r, color); } } }