ReadmeEditor.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor;
  5. using UnityEngine;
  6. using UnityEngine.Rendering;
  7. namespace FlatKit {
  8. [CustomEditor(typeof(FlatKitReadme))]
  9. public class ReadmeEditor : Editor {
  10. private static readonly string AssetName = "Flat Kit";
  11. private static readonly GUID UnityPackageUrpGuid = new GUID("41e59f562b69648719f2424c438758f3");
  12. private static readonly GUID UnityPackageBuiltInGuid = new GUID("f4227764308e84f89a765fbf315e2945");
  13. // 2b85f0b7-3248-4e28-8900-a861e01241ba
  14. // 95b02117-de66-49f0-91e7-cc5f4291cf90
  15. private FlatKitReadme _readme;
  16. private bool _showingVersionMessage;
  17. private string _versionLatest;
  18. private bool _showingClearCacheMessage;
  19. private bool _cacheClearedSuccessfully;
  20. private void OnEnable() {
  21. _readme = serializedObject.targetObject as FlatKitReadme;
  22. if (_readme == null) {
  23. Debug.LogError($"[{AssetName}] Readme error.");
  24. return;
  25. }
  26. _readme.Refresh();
  27. _showingVersionMessage = false;
  28. _showingClearCacheMessage = false;
  29. _versionLatest = null;
  30. AssetDatabase.importPackageStarted += OnImportPackageStarted;
  31. AssetDatabase.importPackageCompleted += OnImportPackageCompleted;
  32. AssetDatabase.importPackageFailed += OnImportPackageFailed;
  33. AssetDatabase.importPackageCancelled += OnImportPackageCancelled;
  34. }
  35. private void OnDisable() {
  36. AssetDatabase.importPackageStarted -= OnImportPackageStarted;
  37. AssetDatabase.importPackageCompleted -= OnImportPackageCompleted;
  38. AssetDatabase.importPackageFailed -= OnImportPackageFailed;
  39. AssetDatabase.importPackageCancelled -= OnImportPackageCancelled;
  40. }
  41. public override void OnInspectorGUI() {
  42. {
  43. EditorGUILayout.LabelField(AssetName, EditorStyles.boldLabel);
  44. DrawUILine(Color.gray, 1, 0);
  45. EditorGUILayout.LabelField($"Version {_readme.FlatKitVersion}", EditorStyles.miniLabel);
  46. EditorGUILayout.Separator();
  47. }
  48. if (GUILayout.Button("Documentation")) {
  49. OpenDocumentation();
  50. }
  51. {
  52. if (_showingVersionMessage) {
  53. if (_versionLatest == null) {
  54. EditorGUILayout.HelpBox($"Checking the latest version...", MessageType.None);
  55. } else {
  56. EditorGUILayout.Space(20);
  57. var local = Version.Parse(_readme.FlatKitVersion);
  58. var remote = Version.Parse(_versionLatest);
  59. if (local >= remote) {
  60. EditorGUILayout.HelpBox($"You have the latest version! {_readme.FlatKitVersion}.",
  61. MessageType.Info);
  62. } else {
  63. EditorGUILayout.HelpBox(
  64. $"Update needed. " +
  65. $"The latest version is {_versionLatest}, but you have {_readme.FlatKitVersion}.",
  66. MessageType.Warning);
  67. #if !UNITY_2020_3_OR_NEWER
  68. EditorGUILayout.HelpBox(
  69. $"Please update Unity to 2020.3 or newer to get the latest version of Flat Kit.",
  70. MessageType.Error);
  71. #endif
  72. }
  73. }
  74. }
  75. if (GUILayout.Button("Check for updates")) {
  76. _showingVersionMessage = true;
  77. _versionLatest = null;
  78. CheckVersion();
  79. }
  80. if (_showingVersionMessage) {
  81. EditorGUILayout.Space(20);
  82. }
  83. }
  84. {
  85. GUILayout.BeginHorizontal();
  86. if (GUILayout.Button("Open support ticket")) {
  87. OpenSupportTicket();
  88. }
  89. if (GUILayout.Button("Copy debug info")) {
  90. CopyDebugInfoToClipboard();
  91. }
  92. GUILayout.EndHorizontal();
  93. }
  94. {
  95. if (!_readme.FlatKitInstalled) {
  96. EditorGUILayout.Separator();
  97. DrawUILine(Color.yellow, 1, 0);
  98. EditorGUILayout.HelpBox(
  99. $"Before using {AssetName} you need to unpack it depending on your project's Render Pipeline.",
  100. MessageType.Warning);
  101. GUILayout.BeginHorizontal();
  102. EditorGUILayout.LabelField($"Unpack {AssetName} for", EditorStyles.label);
  103. if (GUILayout.Button("URP")) {
  104. UnpackFlatKitUrp();
  105. }
  106. if (GUILayout.Button("Built-in RP")) {
  107. UnpackFlatKitBuiltInRP();
  108. }
  109. GUILayout.EndHorizontal();
  110. DrawUILine(Color.yellow, 1, 0);
  111. return;
  112. }
  113. }
  114. {
  115. if (!string.IsNullOrEmpty(_readme.PackageManagerError)) {
  116. EditorGUILayout.Separator();
  117. DrawUILine(Color.yellow, 1, 0);
  118. EditorGUILayout.HelpBox($"Package Manager error: {_readme.PackageManagerError}", MessageType.Warning);
  119. DrawUILine(Color.yellow, 1, 0);
  120. }
  121. }
  122. {
  123. DrawUILine(Color.gray, 1, 20);
  124. EditorGUILayout.LabelField("Package Manager", EditorStyles.label);
  125. if (GUILayout.Button("Clear cache")) {
  126. ClearPackageCache();
  127. }
  128. if (_showingClearCacheMessage) {
  129. if (_cacheClearedSuccessfully) {
  130. EditorGUILayout.HelpBox(
  131. $"Successfully removed cached packages. \n" +
  132. $"Please re-download {AssetName} in the Package Manager.", MessageType.Info);
  133. } else {
  134. EditorGUILayout.HelpBox($"Could not find or clear package cache.", MessageType.Warning);
  135. }
  136. }
  137. EditorGUILayout.Separator();
  138. }
  139. DrawColorSpaceCheck();
  140. {
  141. DrawUILine(Color.gray, 1, 20);
  142. GUILayout.BeginHorizontal();
  143. EditorGUILayout.LabelField("Debug info", EditorStyles.miniBoldLabel);
  144. GUILayout.BeginVertical();
  145. if (GUILayout.Button("Copy", EditorStyles.miniButtonLeft)) {
  146. CopyDebugInfoToClipboard();
  147. }
  148. if (EditorGUIUtility.systemCopyBuffer == GetDebugInfoString()) {
  149. EditorGUILayout.LabelField("Copied!", EditorStyles.miniLabel);
  150. }
  151. GUILayout.EndVertical();
  152. GUILayout.EndHorizontal();
  153. var debugInfo = GetDebugInfo();
  154. var style = new GUIStyle(EditorStyles.miniLabel) {wordWrap = true};
  155. foreach (var s in debugInfo) {
  156. EditorGUILayout.LabelField($" " + s, style);
  157. }
  158. EditorGUILayout.Separator();
  159. }
  160. }
  161. private List<string> GetDebugInfo() {
  162. var renderPipelineAsset = GraphicsSettings.currentRenderPipeline;
  163. if (renderPipelineAsset == null) {
  164. renderPipelineAsset = GraphicsSettings.defaultRenderPipeline;
  165. }
  166. var rpAssetName = renderPipelineAsset == null ? "N/A" : renderPipelineAsset.name;
  167. var renderingPath = "Unknown";
  168. if (Shader.IsKeywordEnabled("_FORWARD_PLUS")) {
  169. renderingPath = "Forward+";
  170. }
  171. var info = new List<string> {
  172. $"{AssetName} version {_readme.FlatKitVersion}",
  173. $"Unity {_readme.UnityVersion}",
  174. $"Dev platform: {Application.platform}",
  175. $"Target platform: {EditorUserBuildSettings.activeBuildTarget}",
  176. $"URP installed: {_readme.UrpInstalled}, version {_readme.UrpVersionInstalled}",
  177. $"Render pipeline: {Shader.globalRenderPipeline}",
  178. $"Render pipeline asset: {rpAssetName}",
  179. $"Rendering path: {renderingPath}",
  180. $"Color space: {PlayerSettings.colorSpace}"
  181. };
  182. var qualityConfig = QualitySettings.renderPipeline == null ? "N/A" : QualitySettings.renderPipeline.name;
  183. info.Add($"Quality config: {qualityConfig}");
  184. var graphicsConfig = GraphicsSettings.currentRenderPipeline == null
  185. ? "N/A"
  186. : GraphicsSettings.currentRenderPipeline.name;
  187. info.Add($"Graphics config: {graphicsConfig}");
  188. return info;
  189. }
  190. private string GetDebugInfoString() {
  191. var info = GetDebugInfo();
  192. {
  193. var keywords = new List<string>();
  194. foreach (var keyword in Shader.enabledGlobalKeywords) {
  195. if (Shader.IsKeywordEnabled(keyword)) {
  196. keywords.Add(keyword.name);
  197. }
  198. }
  199. var keywordsInfo = "Enabled global keywords: " + string.Join(", ", keywords);
  200. info.Add(keywordsInfo);
  201. }
  202. return string.Join("\n", info);
  203. }
  204. private void CopyDebugInfoToClipboard() {
  205. EditorGUIUtility.systemCopyBuffer = GetDebugInfoString();
  206. }
  207. private void ClearPackageCache() {
  208. string path = string.Empty;
  209. if (Application.platform == RuntimePlatform.OSXEditor) {
  210. path = "~/Library/Unity/Asset Store-5.x/Dustyroom/";
  211. }
  212. if (Application.platform == RuntimePlatform.LinuxEditor) {
  213. path = "~/.local/share/unity3d/Asset Store-5.x/Dustyroom/";
  214. }
  215. if (Application.platform == RuntimePlatform.WindowsEditor) {
  216. // This wouldn't understand %APPDATA%.
  217. path = Application.persistentDataPath.Substring(0,
  218. Application.persistentDataPath.IndexOf("AppData", StringComparison.Ordinal)) +
  219. "/AppData/Roaming/Unity/Asset Store-5.x/Dustyroom";
  220. }
  221. if (path == string.Empty) return;
  222. _cacheClearedSuccessfully |= FileUtil.DeleteFileOrDirectory(path);
  223. _showingClearCacheMessage = true;
  224. }
  225. private void UnpackFlatKitUrp() {
  226. string path = AssetDatabase.GUIDToAssetPath(UnityPackageUrpGuid.ToString());
  227. if (path == null) {
  228. Debug.LogError($"<b>[{AssetName}]</b> Could not find the URP package.");
  229. } else {
  230. AssetDatabase.ImportPackage(path, false);
  231. }
  232. }
  233. private void UnpackFlatKitBuiltInRP() {
  234. string path = AssetDatabase.GUIDToAssetPath(UnityPackageBuiltInGuid.ToString());
  235. if (path == null) {
  236. Debug.LogError($"<b>[{AssetName}]</b> Could not find the Built-in RP package.");
  237. } else {
  238. AssetDatabase.ImportPackage(path, false);
  239. }
  240. }
  241. private void OnImportPackageStarted(string packageName) { }
  242. private void OnImportPackageCompleted(string packageName) {
  243. _readme.Refresh();
  244. Repaint();
  245. EditorUtility.SetDirty(this);
  246. }
  247. private void OnImportPackageFailed(string packageName, string errorMessage) {
  248. Debug.LogError($"<b>[{AssetName}]</b> Failed to unpack {packageName}: {errorMessage}.");
  249. }
  250. private void OnImportPackageCancelled(string packageName) {
  251. Debug.LogError($"<b>[{AssetName}]</b> Cancelled unpacking {packageName}.");
  252. }
  253. private void DrawColorSpaceCheck() {
  254. if (PlayerSettings.colorSpace != ColorSpace.Linear) {
  255. DrawUILine(Color.gray, 1, 20);
  256. EditorGUILayout.HelpBox(
  257. $"{AssetName} demo scenes were created for the Linear color space, but your project is " +
  258. $"using {PlayerSettings.colorSpace}.\nThis may result in the demo scenes appearing slightly " +
  259. $"different compared to the Asset Store screenshots.\nOptionally, you may switch the color space " +
  260. $"using the button below.",
  261. MessageType.Warning);
  262. if (GUILayout.Button("Switch player settings to Linear color space")) {
  263. PlayerSettings.colorSpace = ColorSpace.Linear;
  264. }
  265. }
  266. }
  267. private void CheckVersion() {
  268. NetworkManager.GetVersion(version => { _versionLatest = version; });
  269. }
  270. private void OpenSupportTicket() {
  271. Application.OpenURL("https://github.com/Dustyroom/flat-kit-doc/issues/new/choose");
  272. }
  273. private void OpenDocumentation() {
  274. Application.OpenURL("https://flatkit.dustyroom.com");
  275. }
  276. private static void DrawUILine(Color color, int thickness = 2, int padding = 10) {
  277. Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness));
  278. r.height = thickness;
  279. r.y += padding / 2f;
  280. r.x -= 2;
  281. EditorGUI.DrawRect(r, color);
  282. }
  283. }
  284. }