From dbfe8d7453be63ec32f60110d5bff30817cfa973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=80=9D=E6=B5=B7?= <1464576565@qq.com> Date: Tue, 11 Mar 2025 17:46:52 +0800 Subject: [PATCH] modify --- Editor/AlicizaX.EditorExtension.Editor.asmdef | 10 +- Editor/Build.meta | 3 + Editor/Build/BuildCLI.meta | 3 + Editor/Build/BuildCLI/AppBuildHelper.cs | 64 ++ Editor/Build/BuildCLI/AppBuildHelper.cs.meta | 3 + Editor/Build/BuildCLI/BuildParameter.cs | 36 + Editor/Build/BuildCLI/BuildParameter.cs.meta | 3 + Editor/Build/BuildCLI/ResourceBuildHelper.cs | 117 +++ .../BuildCLI/ResourceBuildHelper.cs.meta | 3 + Editor/Build/BuildCLI/TestBuildCLI.cs | 60 ++ Editor/Build/BuildCLI/TestBuildCLI.cs.meta | 3 + Editor/EditorIcons.cs | 746 ++++++++++++++++++ Editor/EditorIcons.cs.meta | 11 + Editor/EditorToolFunctionAttribute.cs | 90 +++ Editor/EditorToolFunctionAttribute.cs.meta | 3 + Plugins.meta => Editor/Postprocessor.meta | 2 +- Editor/Postprocessor/Atlas.meta | 3 + .../Postprocessor/Atlas/AtlasConfiguration.cs | 24 + .../Atlas/AtlasConfiguration.cs.meta | 3 + .../Postprocessor/Atlas/AtlasEditorWindow.cs | 95 +++ .../Atlas/AtlasEditorWindow.cs.meta | 3 + .../Postprocessor/Atlas/AtlasPostprocessor.cs | 38 + .../Atlas/AtlasPostprocessor.cs.meta | 3 + Editor/Postprocessor/Atlas/AtlasProcessor.cs | 210 +++++ .../Atlas/AtlasProcessor.cs.meta | 3 + Editor/Postprocessor/SpritePostprocessor.cs | 549 +++++++++++++ .../Postprocessor/SpritePostprocessor.cs.meta | 11 + Editor/ToolBar.meta | 8 + Editor/ToolBar/BuildSettingWindow.cs | 26 + Editor/ToolBar/BuildSettingWindow.cs.meta | 3 + Editor/ToolBar/EditorQuickToolBar.cs | 62 ++ Editor/ToolBar/EditorQuickToolBar.cs.meta | 3 + Editor/ToolBar/ResourceModeDropdownField.cs | 65 ++ .../ToolBar/ResourceModeDropdownField.cs.meta | 3 + Editor/ToolBar/SwitchSceneToolBar.cs | 101 +++ Editor/ToolBar/SwitchSceneToolBar.cs.meta | 3 + 36 files changed, 2371 insertions(+), 2 deletions(-) create mode 100644 Editor/Build.meta create mode 100644 Editor/Build/BuildCLI.meta create mode 100644 Editor/Build/BuildCLI/AppBuildHelper.cs create mode 100644 Editor/Build/BuildCLI/AppBuildHelper.cs.meta create mode 100644 Editor/Build/BuildCLI/BuildParameter.cs create mode 100644 Editor/Build/BuildCLI/BuildParameter.cs.meta create mode 100644 Editor/Build/BuildCLI/ResourceBuildHelper.cs create mode 100644 Editor/Build/BuildCLI/ResourceBuildHelper.cs.meta create mode 100644 Editor/Build/BuildCLI/TestBuildCLI.cs create mode 100644 Editor/Build/BuildCLI/TestBuildCLI.cs.meta create mode 100644 Editor/EditorIcons.cs create mode 100644 Editor/EditorIcons.cs.meta create mode 100644 Editor/EditorToolFunctionAttribute.cs create mode 100644 Editor/EditorToolFunctionAttribute.cs.meta rename Plugins.meta => Editor/Postprocessor.meta (77%) create mode 100644 Editor/Postprocessor/Atlas.meta create mode 100644 Editor/Postprocessor/Atlas/AtlasConfiguration.cs create mode 100644 Editor/Postprocessor/Atlas/AtlasConfiguration.cs.meta create mode 100644 Editor/Postprocessor/Atlas/AtlasEditorWindow.cs create mode 100644 Editor/Postprocessor/Atlas/AtlasEditorWindow.cs.meta create mode 100644 Editor/Postprocessor/Atlas/AtlasPostprocessor.cs create mode 100644 Editor/Postprocessor/Atlas/AtlasPostprocessor.cs.meta create mode 100644 Editor/Postprocessor/Atlas/AtlasProcessor.cs create mode 100644 Editor/Postprocessor/Atlas/AtlasProcessor.cs.meta create mode 100644 Editor/Postprocessor/SpritePostprocessor.cs create mode 100644 Editor/Postprocessor/SpritePostprocessor.cs.meta create mode 100644 Editor/ToolBar.meta create mode 100644 Editor/ToolBar/BuildSettingWindow.cs create mode 100644 Editor/ToolBar/BuildSettingWindow.cs.meta create mode 100644 Editor/ToolBar/EditorQuickToolBar.cs create mode 100644 Editor/ToolBar/EditorQuickToolBar.cs.meta create mode 100644 Editor/ToolBar/ResourceModeDropdownField.cs create mode 100644 Editor/ToolBar/ResourceModeDropdownField.cs.meta create mode 100644 Editor/ToolBar/SwitchSceneToolBar.cs create mode 100644 Editor/ToolBar/SwitchSceneToolBar.cs.meta diff --git a/Editor/AlicizaX.EditorExtension.Editor.asmdef b/Editor/AlicizaX.EditorExtension.Editor.asmdef index efcb860..e36a1b4 100644 --- a/Editor/AlicizaX.EditorExtension.Editor.asmdef +++ b/Editor/AlicizaX.EditorExtension.Editor.asmdef @@ -1,7 +1,15 @@ { "name": "AlicizaX.EditorExtension.Editor", "rootNamespace": "AlicizaX.EditorExtension.Editor", - "references": [], + "references": [ + "GUID:8d62da4aabd2a19419c7378d23ea5849", + "GUID:75b6f2078d190f14dbda4a5b747d709c", + "GUID:e34a5702dd353724aa315fb8011f08c3", + "GUID:4d1926c9df5b052469a1c63448b7609a", + "GUID:be2f20a77f3232f44b9711ef43234aac", + "GUID:a19b414bea3b97240a91aeab9a8eab36", + "GUID:acfef7cabed3b0a42b25edb1cd4fa259" + ], "includePlatforms": [ "Editor" ], diff --git a/Editor/Build.meta b/Editor/Build.meta new file mode 100644 index 0000000..14b8047 --- /dev/null +++ b/Editor/Build.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cf685193bc1e8cd4193c4c0003a1ef33 +timeCreated: 1737627977 \ No newline at end of file diff --git a/Editor/Build/BuildCLI.meta b/Editor/Build/BuildCLI.meta new file mode 100644 index 0000000..cdbc8ab --- /dev/null +++ b/Editor/Build/BuildCLI.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 69ea7963a8cfa4645b9345e57aef8331 +timeCreated: 1737867267 \ No newline at end of file diff --git a/Editor/Build/BuildCLI/AppBuildHelper.cs b/Editor/Build/BuildCLI/AppBuildHelper.cs new file mode 100644 index 0000000..2f3035e --- /dev/null +++ b/Editor/Build/BuildCLI/AppBuildHelper.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using AlicizaX.Editor; +using AlicizaX.Runtime; +using UnityEditor; +using UnityEngine; + +public static class AppBuildHelper +{ + private const string _entryScene = "Assets/Scenes/Main.unity"; + private const string AppBuilderSettingPath = "Assets/Resources/AppBuilderSetting.bytes"; + + public static void BuildApplication(AppBuildParameter appBuildParameter) + { + if (!Directory.Exists(appBuildParameter.outPutPath)) + { + Directory.CreateDirectory(appBuildParameter.outPutPath); + } + + Debug.Log("Starting build application"); + + AppBuilderSetting appBuilderSetting = new AppBuilderSetting(); + appBuilderSetting.Language = appBuildParameter.language; + appBuilderSetting.DebugMode = appBuildParameter.developBuild; + appBuilderSetting.ResMode = appBuildParameter.resMode; + File.WriteAllText(AppBuilderSettingPath, Utility.Json.ToJson(appBuilderSetting)); + + Debug.Log("Generate AppBuilderSetting.bytes"); + + SyncAssemblyContent.GenerateAssemblyLoadData(); + + try + { + var options = new BuildPlayerOptions + { + scenes = new[] { _entryScene }, + locationPathName = Path.Combine(appBuildParameter.outPutPath, appBuildParameter.fileName), + target = appBuildParameter.buildTarget, + options = appBuildParameter.developBuild ? BuildOptions.Development : BuildOptions.None + }; + + var report = BuildPipeline.BuildPlayer(options); + HandleBuildReport(report); + } + catch (Exception e) + { + Debug.Log($"构建过程中发生异常: {e.Message}"); + } + } + + private static void HandleBuildReport(UnityEditor.Build.Reporting.BuildReport report) + { + if (report.summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded) + { + Debug.Log($"整包构建完成:${report.summary.outputPath}"); + } + else + { + Debug.Log($"错误信息: {report.SummarizeErrors()}"); + } + } +} diff --git a/Editor/Build/BuildCLI/AppBuildHelper.cs.meta b/Editor/Build/BuildCLI/AppBuildHelper.cs.meta new file mode 100644 index 0000000..1bd56d3 --- /dev/null +++ b/Editor/Build/BuildCLI/AppBuildHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 154ce1f8cc3455246af4a6501d246f02 +timeCreated: 1740128549 \ No newline at end of file diff --git a/Editor/Build/BuildCLI/BuildParameter.cs b/Editor/Build/BuildCLI/BuildParameter.cs new file mode 100644 index 0000000..ed9219e --- /dev/null +++ b/Editor/Build/BuildCLI/BuildParameter.cs @@ -0,0 +1,36 @@ +using System; +using AlicizaX.Runtime; +using UnityEditor; +using UnityEngine.Serialization; +using YooAsset.Editor; + +[System.Serializable] +public struct AppBuildParameter +{ + public BuildTarget buildTarget; + public string outPutPath; + public bool developBuild; + public int resMode; + public string fileName; + public Language language; +} + + +public struct ResourceBuildParameter +{ + public BuildTarget ResourceBuildTarget; + public string PackageVersion; + public bool UseDefaultPackageVersion; + public string OutputPath; + public ResourceBuildMode BuildMode; + + public const ECompressOption CompressOption = ECompressOption.LZ4; + public const EFileNameStyle FileNameStyle = EFileNameStyle.BundleName_HashName; + public const string EncryptionServiceType = "AlicizaX.Resource.Editor.FileOffsetEncryption"; +} + +public enum ResourceBuildMode +{ + Offline, + Online, +} diff --git a/Editor/Build/BuildCLI/BuildParameter.cs.meta b/Editor/Build/BuildCLI/BuildParameter.cs.meta new file mode 100644 index 0000000..947c929 --- /dev/null +++ b/Editor/Build/BuildCLI/BuildParameter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4d5b605d55cc82844b76260841f92475 +timeCreated: 1741577226 \ No newline at end of file diff --git a/Editor/Build/BuildCLI/ResourceBuildHelper.cs b/Editor/Build/BuildCLI/ResourceBuildHelper.cs new file mode 100644 index 0000000..bf7dbc0 --- /dev/null +++ b/Editor/Build/BuildCLI/ResourceBuildHelper.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEngine; +using YooAsset; +using YooAsset.Editor; + +public static class ResourceBuildHelper +{ + private const bool EnableSharePack = true; + private const string BuildPackageName = "DefaultPackage"; + + private static string GeneratePackageVersion() + { + int totalMinutes = DateTime.Now.Hour * 60 + DateTime.Now.Minute; + return DateTime.Now.ToString("yyyy-MM-dd") + "-" + totalMinutes; + } + + public static void BuildResourcePackage(ResourceBuildParameter buildParameter) + { + if (!Directory.Exists(buildParameter.OutputPath)) + { + Directory.CreateDirectory(buildParameter.OutputPath); + } + + try + { + string copyParams = string.Empty; + EBuildinFileCopyOption copyOption = EBuildinFileCopyOption.None; + if (buildParameter.BuildMode == ResourceBuildMode.Online) + { + copyOption = EBuildinFileCopyOption.ClearAndCopyByTags; + copyParams = "Launch"; + } + else + { + copyOption = EBuildinFileCopyOption.ClearAndCopyAll; + } + + var parameters = new ScriptableBuildParameters + { + BuildOutputRoot = buildParameter.OutputPath, + BuildTarget = buildParameter.ResourceBuildTarget, + PackageName = BuildPackageName, + BuildBundleType = (int)EBuildBundleType.AssetBundle, + BuildPipeline = EBuildPipeline.ScriptableBuildPipeline.ToString(), + BuildinFileRoot = AssetBundleBuilderHelper.GetStreamingAssetsRoot(), + PackageVersion = buildParameter.UseDefaultPackageVersion ? GeneratePackageVersion() : buildParameter.PackageVersion, + CompressOption = ResourceBuildParameter.CompressOption, + FileNameStyle = ResourceBuildParameter.FileNameStyle, + VerifyBuildingResult = true, + ClearBuildCacheFiles = false, + BuildinFileCopyOption = copyOption, + BuildinFileCopyParams = copyParams, + EnableSharePackRule = EnableSharePack, + EncryptionServices = CreateEncryptionInstance(ResourceBuildParameter.EncryptionServiceType) + }; + + ScriptableBuildPipeline pipeline = new ScriptableBuildPipeline(); + var report = pipeline.Run(parameters, true); + + if (report.Success) + { + // if (_copyAfterBuild && !string.IsNullOrEmpty(_copyDestination)) + // { + // CopyFiles(report.OutputPackageDirectory, _copyDestination); + // } + Debug.Log($"AB包构建完成!\n输出目录: {report.OutputPackageDirectory}"); + } + else + { + Debug.Log($"错误信息: {report.ErrorInfo}"); + } + } + catch (Exception e) + { + Debug.LogException(e); + } + } + + private static void CopyFiles(string source, string destination) + { + try + { + if (!Directory.Exists(destination)) + { + Directory.CreateDirectory(destination); + } + + foreach (string file in Directory.GetFiles(source)) + { + File.Copy(file, Path.Combine(destination, Path.GetFileName(file)), true); + } + + Debug.Log($"文件拷贝完成: {source} -> {destination}"); + } + catch (Exception e) + { + Debug.LogError($"文件拷贝失败: {e.Message}"); + } + } + + private static IEncryptionServices CreateEncryptionInstance(string encryptionService) + { + if (string.IsNullOrEmpty(encryptionService)) return null; + + var type = Type.GetType(encryptionService); + if (type != null) + { + return (IEncryptionServices)Activator.CreateInstance(type); + } + + return null; + } +} diff --git a/Editor/Build/BuildCLI/ResourceBuildHelper.cs.meta b/Editor/Build/BuildCLI/ResourceBuildHelper.cs.meta new file mode 100644 index 0000000..ec1cb06 --- /dev/null +++ b/Editor/Build/BuildCLI/ResourceBuildHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d0418e1e75999064ca53a72ff542a08c +timeCreated: 1740128311 \ No newline at end of file diff --git a/Editor/Build/BuildCLI/TestBuildCLI.cs b/Editor/Build/BuildCLI/TestBuildCLI.cs new file mode 100644 index 0000000..164f6d9 --- /dev/null +++ b/Editor/Build/BuildCLI/TestBuildCLI.cs @@ -0,0 +1,60 @@ +using System.IO; +using AlicizaX.Runtime; +using UnityEditor; +using UnityEngine; +using YooAsset; +using YooAsset.Editor; + +namespace BuildCLI +{ + public static class TestBuildCLI + { + [MenuItem("Test/Build Offline Exe")] + public static void TestBuildExe() + { + BuildOfflineRes(); + AppBuildParameter parameter = new AppBuildParameter(); + parameter.developBuild = false; + parameter.outPutPath = "../Build"; + parameter.fileName = "Aliciza.exe"; + parameter.buildTarget = BuildTarget.StandaloneWindows; + parameter.resMode = (int)EPlayMode.OfflinePlayMode; + parameter.language = Language.ChineseSimplified; + AppBuildHelper.BuildApplication(parameter); + } + + [MenuItem("Test/Build Online Exe")] + public static void TestBuildOnlineExe() + { + AppBuildParameter parameter = new AppBuildParameter(); + parameter.developBuild = false; + parameter.outPutPath = "../Build"; + parameter.fileName = "Aliciza.exe"; + parameter.buildTarget = BuildTarget.StandaloneWindows; + parameter.resMode = (int)EPlayMode.HostPlayMode; + parameter.language = Language.ChineseSimplified; + AppBuildHelper.BuildApplication(parameter); + } + + [MenuItem("Test/Build OnlineRes")] + public static void TestBuildRes() + { + ResourceBuildParameter buildParameter = new ResourceBuildParameter(); + buildParameter.ResourceBuildTarget = BuildTarget.StandaloneWindows; + buildParameter.UseDefaultPackageVersion = true; + buildParameter.OutputPath = "../Bundle"; + buildParameter.BuildMode = ResourceBuildMode.Online; + ResourceBuildHelper.BuildResourcePackage(buildParameter); + } + + public static void BuildOfflineRes() + { + ResourceBuildParameter buildParameter = new ResourceBuildParameter(); + buildParameter.ResourceBuildTarget = BuildTarget.StandaloneWindows; + buildParameter.UseDefaultPackageVersion = true; + buildParameter.OutputPath = "../Bundle"; + buildParameter.BuildMode = ResourceBuildMode.Offline; + ResourceBuildHelper.BuildResourcePackage(buildParameter); + } + } +} diff --git a/Editor/Build/BuildCLI/TestBuildCLI.cs.meta b/Editor/Build/BuildCLI/TestBuildCLI.cs.meta new file mode 100644 index 0000000..8d5bab0 --- /dev/null +++ b/Editor/Build/BuildCLI/TestBuildCLI.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6c94214f2cdc01f4f8b90720e5226acd +timeCreated: 1741578950 \ No newline at end of file diff --git a/Editor/EditorIcons.cs b/Editor/EditorIcons.cs new file mode 100644 index 0000000..ca544a6 --- /dev/null +++ b/Editor/EditorIcons.cs @@ -0,0 +1,746 @@ +#if UNITY_EDITOR + +using System; +using UnityEngine; +using UnityEditor; +using System.Collections.Generic; +using System.Linq; +using System.IO; + +public class EditorIcons : EditorWindow +{ + [MenuItem("Tools/Editor Icons %e", priority = -1001)] + public static void EditorIconsOpen() + { +#if UNITY_2018 + var w = GetWindow("Editor Icons"); +#else + var w = CreateWindow("Editor Icons"); +#endif + w.ShowUtility(); + w.minSize = new Vector2(320, 450); + } + + static bool viewBigIcons = true; + + static bool darkPreview = true; + + Vector2 scroll; + + int buttonSize = 70; + + string search = ""; + + void SearchGUI() + { + using (new GUILayout.HorizontalScope()) + { + if (isWide) GUILayout.Space(10); + +#if UNITY_2018 + search = EditorGUILayout.TextField(search, EditorStyles.toolbarTextField); +#else + search = EditorGUILayout.TextField(search, EditorStyles.toolbarSearchField); +#endif + if (GUILayout.Button(EditorGUIUtility.IconContent("winbtn_mac_close_h"), //SVN_DeletedLocal + EditorStyles.toolbarButton, + GUILayout.Width(22)) + ) search = ""; + } + } + + bool isWide => Screen.width > 550; + + bool doSearch => !string.IsNullOrWhiteSpace(search) && search != ""; + + GUIContent GetIcon(string icon_name) + { + GUIContent valid = null; + Debug.unityLogger.logEnabled = false; + if (!string.IsNullOrEmpty(icon_name)) valid = EditorGUIUtility.IconContent(icon_name); + Debug.unityLogger.logEnabled = true; + return valid?.image == null ? null : valid; + } + + void SaveIcon(string icon_name) + { + Texture2D tex = EditorGUIUtility.IconContent(icon_name).image as Texture2D; + + if (tex != null) + { + string path = EditorUtility.SaveFilePanel( + "Save icon", "", icon_name, "png"); + + if (path != null) + { + try + { +#if UNITY_2018 + Texture2D outTex = new Texture2D( + tex.width, tex.height, + tex.format, true); +#else + Texture2D outTex = new Texture2D( + tex.width, tex.height, + tex.format, tex.mipmapCount, true); +#endif + + Graphics.CopyTexture(tex, outTex); + + File.WriteAllBytes(path, outTex.EncodeToPNG()); + } + catch (System.Exception e) + { + Debug.LogError("Cannot save the icon : " + e.Message); + } + } + } + else + { + Debug.LogError("Cannot save the icon : null texture error!"); + } + } + + void SaveAllIcons() + { + var folderpath = EditorUtility.SaveFolderPanel("", "", ""); + try + { + foreach (string icon in ico_list) + { + var split = icon.Split('/').Last(); + Texture2D tex = EditorGUIUtility.IconContent(icon).image as Texture2D; + + if (tex == null) continue; + if (string.IsNullOrWhiteSpace(folderpath)) + { + Debug.LogError("Folder path invalid..."); + break; + } + + var path = folderpath + "//" + $"{split}.png"; + + if (File.Exists(path)) + { + Debug.Log($"file already written with name aborting write: {path}"); + } + else + { +#if UNITY_2018 + Texture2D outTex = new Texture2D( + tex.width, tex.height, + tex.format, true); +#else + Texture2D outTex = new Texture2D( + tex.width, tex.height, + tex.format, tex.mipmapCount, true); +#endif + + Graphics.CopyTexture(tex, outTex); + + + File.WriteAllBytes(path, outTex.EncodeToPNG()); + } + } + } + catch (Exception e) + { + Debug.LogError("Cannot save the icons: " + e.Message); + } + } + + private void OnEnable() + { + //InitIcons(); + //var all_icons = iconContentListAll.Select(x => x.tooltip).ToArray(); + var all_icons = ico_list.Where(x => GetIcon(x) != null); + //List found = new List(); + List unique = new List(); + //var skip_flag = HideFlags.HideInInspector | HideFlags.HideAndDontSave; + //int unique_to_resources = 0, skipped_empty_str = 0, skipped_flags = 0, + // skipped_not_persistent = 0, skipped_nulls = 0, unique_to_list = 0; + + foreach (Texture2D x in Resources.FindObjectsOfTypeAll()) + { + //if (string.IsNullOrEmpty(x.name)) skipped_empty_str++; // skipped 10 empty + //if (!EditorUtility.IsPersistent(x)) skipped_not_persistent++; // skipped 39 none persistent + //if (x.hideFlags != HideFlags.HideAndDontSave && x.hideFlags != skip_flag) skipped_flags++; // skipped 27 icons + + GUIContent icoContent = GetIcon(x.name); + if (icoContent == null) continue; // skipped 14 icons + //{ + // skipped_nulls++; + // continue; + //} + + if (!all_icons.Contains(x.name)) + { + //unique_to_resources++; + unique.Add(x.name); + } + + //found.Add( x.name ); + } + + //foreach (var ico in all_icons) if (!found.Contains(ico)) unique_to_list++; + + //Debug.Log( $"Resources skipped nulls={skipped_nulls} empty={skipped_empty_str} flags={skipped_flags}" ); + //Debug.Log("Resources skipped_not_persistent=" + skipped_not_persistent); + //Debug.Log($"totals , list: {all_icons.Length} resource: {found.Count}"); + //Debug.Log($"Unique list={ unique_to_list } resources={unique_to_resources}") ; + + ico_list = ico_list.ToList().Concat(unique).ToArray(); + + // Static list icons count : 1315 ( unique = 749 ) + // Found icons in resources : 1416 ( unique = 855 ) + + Resources.UnloadUnusedAssets(); + System.GC.Collect(); + } + + private void OnGUI() + { + var ppp = EditorGUIUtility.pixelsPerPoint; + + InitIcons(); + + if (!isWide) SearchGUI(); + + using (new GUILayout.HorizontalScope(EditorStyles.toolbar)) + { + if (GUILayout.Button("Save all icons to folder...", EditorStyles.miniButton)) SaveAllIcons(); + GUILayout.Label("Select what icons to show", GUILayout.Width(160)); + viewBigIcons = GUILayout.SelectionGrid( + viewBigIcons ? 1 : 0, new string[] { "Small", "Big" }, + 2, EditorStyles.toolbarButton) == 1; + + if (isWide) SearchGUI(); + } + + if (isWide) GUILayout.Space(3); + + using (var scope = new GUILayout.ScrollViewScope(scroll)) + { + GUILayout.Space(10); + + scroll = scope.scrollPosition; + + buttonSize = viewBigIcons ? 70 : 40; + + // scrollbar_width = ~ 12.5 + var render_width = (Screen.width / ppp - 13f); + var gridW = Mathf.FloorToInt(render_width / buttonSize); + var margin_left = (render_width - buttonSize * gridW) / 2; + + int row = 0, index = 0; + + List iconList; + + if (doSearch) iconList = iconContentListAll.Where(x => x.tooltip.ToLower() + .Contains(search.ToLower())).ToList(); + else iconList = viewBigIcons ? iconContentListBig : iconContentListSmall; + + while (index < iconList.Count) + { + using (new GUILayout.HorizontalScope()) + { + GUILayout.Space(margin_left); + + for (var i = 0; i < gridW; ++i) + { + int k = i + row * gridW; + + var icon = iconList[k]; + + if (GUILayout.Button(icon, + iconButtonStyle, + GUILayout.Width(buttonSize), + GUILayout.Height(buttonSize))) + { + EditorGUI.FocusTextInControl(""); + iconSelected = icon; + } + + index++; + + if (index == iconList.Count) break; + } + } + + row++; + } + + GUILayout.Space(10); + } + + + if (iconSelected == null) return; + + GUILayout.FlexibleSpace(); + + using (new GUILayout.HorizontalScope(EditorStyles.helpBox, GUILayout.MaxHeight(viewBigIcons ? 140 : 120))) + { + using (new GUILayout.VerticalScope(GUILayout.Width(130))) + { + GUILayout.Space(2); + + GUILayout.Button(iconSelected, + darkPreview ? iconPreviewBlack : iconPreviewWhite, + GUILayout.Width(128), GUILayout.Height(viewBigIcons ? 128 : 40)); + + GUILayout.Space(5); + + darkPreview = GUILayout.SelectionGrid( + darkPreview ? 1 : 0, new string[] { "Light", "Dark" }, + 2, EditorStyles.miniButton) == 1; + + GUILayout.FlexibleSpace(); + } + + GUILayout.Space(10); + + using (new GUILayout.VerticalScope()) + { + var s = $"Size: {iconSelected.image.width}x{iconSelected.image.height}"; + s += "\nIs Pro Skin Icon: " + (iconSelected.tooltip.IndexOf("d_") == 0 ? "Yes" : "No"); + s += $"\nTotal {iconContentListAll.Count} icons"; + GUILayout.Space(5); + EditorGUILayout.HelpBox(s, MessageType.None); + GUILayout.Space(5); + EditorGUILayout.TextField("EditorGUIUtility.IconContent(\"" + iconSelected.tooltip + "\")"); + GUILayout.Space(5); + if (GUILayout.Button("Copy to clipboard", EditorStyles.miniButton)) + EditorGUIUtility.systemCopyBuffer = iconSelected.tooltip; + if (GUILayout.Button("Save icon to file ...", EditorStyles.miniButton)) + SaveIcon(iconSelected.tooltip); + } + + GUILayout.Space(10); + + if (GUILayout.Button("X", GUILayout.ExpandHeight(true))) + { + iconSelected = null; + } + + } + } + + static GUIContent iconSelected; + static List iconContentListAll; + static List iconContentListSmall; + static List iconContentListBig; + static List iconMissingNames; + static GUIStyle iconButtonStyle = null; + static GUIStyle iconPreviewBlack = null; + static GUIStyle iconPreviewWhite = null; + + void AllTheTEXTURES(ref GUIStyle s, Texture2D t) + { + s.hover.background = s.onHover.background = s.focused.background = s.onFocused.background = s.active.background = s.onActive.background = s.normal.background = s.onNormal.background = t; + s.hover.scaledBackgrounds = s.onHover.scaledBackgrounds = s.focused.scaledBackgrounds = s.onFocused.scaledBackgrounds = s.active.scaledBackgrounds = s.onActive.scaledBackgrounds = s.normal.scaledBackgrounds = s.onNormal.scaledBackgrounds = new Texture2D[] { t }; + } + + Texture2D Texture2DPixel(Color c) + { + Texture2D t = new Texture2D(1, 1); + t.SetPixel(0, 0, c); + t.Apply(); + return t; + } + + void InitIcons() + { + if (iconContentListSmall != null) return; + + iconButtonStyle = new GUIStyle(EditorStyles.miniButton); + iconButtonStyle.margin = new RectOffset(0, 0, 0, 0); + iconButtonStyle.fixedHeight = 0; + + iconPreviewBlack = new GUIStyle(iconButtonStyle); + AllTheTEXTURES(ref iconPreviewBlack, Texture2DPixel(new Color(0.15f, 0.15f, 0.15f))); + + iconPreviewWhite = new GUIStyle(iconButtonStyle); + AllTheTEXTURES(ref iconPreviewWhite, Texture2DPixel(new Color(0.85f, 0.85f, 0.85f))); + + iconMissingNames = new List(); + iconContentListSmall = new List(); + iconContentListBig = new List(); + iconContentListAll = new List(); + + for (var i = 0; i < ico_list.Length; ++i) + { + GUIContent ico = GetIcon(ico_list[i]); + + if (ico == null) + { + iconMissingNames.Add(ico_list[i]); + continue; + } + + ico.tooltip = ico_list[i]; + + iconContentListAll.Add(ico); + + if (!(ico.image.width <= 36 || ico.image.height <= 36)) + iconContentListBig.Add(ico); + else iconContentListSmall.Add(ico); + } + } + + // https://gist.github.com/MattRix/c1f7840ae2419d8eb2ec0695448d4321 + // https://unitylist.com/p/5c3/Unity-editor-icons + + #region ICONS + + public static string[] ico_list = + { + "_Help","_Popup","aboutwindow.mainheader","ageialogo","AlphabeticalSorting","Animation.AddEvent", + "Animation.AddKeyframe","Animation.EventMarker","Animation.FirstKey","Animation.LastKey", + "Animation.NextKey","Animation.Play","Animation.PrevKey","Animation.Record","Animation.SequencerLink", + "animationanimated","animationdopesheetkeyframe","animationkeyframe","animationnocurve", + "animationvisibilitytoggleoff","animationvisibilitytoggleon","AnimationWrapModeMenu","AssemblyLock", + "Asset Store","Audio Mixer","AvatarCompass","AvatarController.Layer","AvatarController.LayerHover", + "AvatarController.LayerSelected","BodyPartPicker","BodySilhouette","DotFill","DotFrame","DotFrameDotted", + "DotSelection","Head","HeadIk","HeadZoom","HeadZoomSilhouette","LeftArm","LeftFeetIk","LeftFingers", + "LeftFingersIk","LeftHandZoom","LeftHandZoomSilhouette","LeftLeg","MaskEditor_Root","RightArm","RightFeetIk", + "RightFingers","RightFingersIk","RightHandZoom","RightHandZoomSilhouette","RightLeg","Torso","AvatarPivot", + "back","back@2x","beginButton-On","beginButton","blendKey","blendKeyOverlay","blendKeySelected", + "blendSampler","blueGroove","BuildSettings.Android","BuildSettings.Android.Small","BuildSettings.Broadcom", + "BuildSettings.Editor","BuildSettings.Editor.Small","BuildSettings.Facebook", + "BuildSettings.Facebook.Small","BuildSettings.FlashPlayer","BuildSettings.FlashPlayer.Small", + "BuildSettings.iPhone","BuildSettings.iPhone.Small","BuildSettings.Lumin","BuildSettings.Lumin.small", + "BuildSettings.Metro","BuildSettings.Metro.Small","BuildSettings.N3DS","BuildSettings.N3DS.Small", + "BuildSettings.PS4","BuildSettings.PS4.Small","BuildSettings.PSM","BuildSettings.PSM.Small", + "BuildSettings.PSP2","BuildSettings.PSP2.Small","BuildSettings.SelectedIcon","BuildSettings.Standalone", + "BuildSettings.Standalone.Small","BuildSettings.StandaloneBroadcom.Small", + "BuildSettings.StandaloneGLES20Emu.Small","BuildSettings.StandaloneGLESEmu", + "BuildSettings.StandaloneGLESEmu.Small","BuildSettings.Switch","BuildSettings.Switch.Small", + "BuildSettings.tvOS","BuildSettings.tvOS.Small","BuildSettings.Web","BuildSettings.Web.Small", + "BuildSettings.WebGL","BuildSettings.WebGL.Small","BuildSettings.WP8","BuildSettings.WP8.Small", + "BuildSettings.Xbox360","BuildSettings.Xbox360.Small","BuildSettings.XboxOne", + "BuildSettings.XboxOne.Small","BuildSettings.Xiaomi","Camera Gizmo","CheckerFloor","Clipboard", + "ClothInspector.PaintTool","ClothInspector.PaintValue","ClothInspector.SelectTool", + "ClothInspector.SettingsTool","ClothInspector.ViewValue","CloudConnect","Collab.Build", + "Collab.BuildFailed","Collab.BuildSucceeded","Collab.FileAdded","Collab.FileConflict","Collab.FileDeleted", + "Collab.FileIgnored","Collab.FileMoved","Collab.FileUpdated","Collab.FolderAdded","Collab.FolderConflict", + "Collab.FolderDeleted","Collab.FolderIgnored","Collab.FolderMoved","Collab.FolderUpdated", + "Collab.NoInternet","Collab","Collab.Warning","CollabConflict","CollabError","CollabNew","CollabOffline", + "CollabProgress","CollabPull","CollabPush","ColorPicker.ColorCycle","ColorPicker.CycleColor", + "ColorPicker.CycleSlider","ColorPicker.SliderCycle","console.erroricon.inactive.sml","console.erroricon", + "console.erroricon.sml","console.infoicon","console.infoicon.sml","console.warnicon.inactive.sml", + "console.warnicon","console.warnicon.sml","curvekeyframe","curvekeyframeselected", + "curvekeyframeselectedoverlay","curvekeyframesemiselectedoverlay","curvekeyframeweighted","CustomSorting", + "d__Popup","d_aboutwindow.mainheader","d_ageialogo","d_AlphabeticalSorting","d_Animation.AddEvent", + "d_Animation.AddKeyframe","d_Animation.EventMarker","d_Animation.FirstKey","d_Animation.LastKey", + "d_Animation.NextKey","d_Animation.Play","d_Animation.PrevKey","d_Animation.Record", + "d_Animation.SequencerLink","d_animationanimated","d_animationkeyframe","d_animationnocurve", + "d_animationvisibilitytoggleoff","d_animationvisibilitytoggleon","d_AnimationWrapModeMenu", + "d_AS Badge Delete","d_AS Badge New","d_AssemblyLock","d_Asset Store","d_Audio Mixer", + "d_AvatarBlendBackground","d_AvatarBlendLeft","d_AvatarBlendLeftA","d_AvatarBlendRight", + "d_AvatarBlendRightA","d_AvatarCompass","d_AvatarPivot","d_back","d_back@2x","d_beginButton-On", + "d_beginButton","d_blueGroove","d_BuildSettings.Android","d_BuildSettings.Android.Small", + "d_BuildSettings.Broadcom","d_BuildSettings.FlashPlayer","d_BuildSettings.FlashPlayer.Small", + "d_BuildSettings.iPhone","d_BuildSettings.iPhone.Small","d_BuildSettings.Lumin", + "d_BuildSettings.Lumin.small","d_BuildSettings.PS4","d_BuildSettings.PS4.Small","d_BuildSettings.PSP2", + "d_BuildSettings.PSP2.Small","d_BuildSettings.SelectedIcon","d_BuildSettings.Standalone", + "d_BuildSettings.Standalone.Small","d_BuildSettings.tvOS","d_BuildSettings.tvOS.Small", + "d_BuildSettings.Web","d_BuildSettings.Web.Small","d_BuildSettings.WebGL","d_BuildSettings.WebGL.Small", + "d_BuildSettings.Xbox360","d_BuildSettings.Xbox360.Small","d_BuildSettings.XboxOne", + "d_BuildSettings.XboxOne.Small","d_CheckerFloor","d_CloudConnect","d_Collab.FileAdded", + "d_Collab.FileConflict","d_Collab.FileDeleted","d_Collab.FileIgnored","d_Collab.FileMoved", + "d_Collab.FileUpdated","d_Collab.FolderAdded","d_Collab.FolderConflict","d_Collab.FolderDeleted", + "d_Collab.FolderIgnored","d_Collab.FolderMoved","d_Collab.FolderUpdated","d_ColorPicker.CycleColor", + "d_ColorPicker.CycleSlider","d_console.erroricon","d_console.erroricon.sml","d_console.infoicon", + "d_console.infoicon.sml","d_console.warnicon","d_console.warnicon.sml","d_curvekeyframe", + "d_curvekeyframeselected","d_curvekeyframeselectedoverlay","d_curvekeyframesemiselectedoverlay", + "d_curvekeyframeweighted","d_CustomSorting","d_DefaultSorting","d_EditCollider","d_editcollision_16", + "d_editconstraints_16","d_editicon.sml","d_endButton-On","d_endButton","d_eyeDropper.Large", + "d_eyeDropper.sml","d_Favorite","d_FilterByLabel","d_FilterByType","d_FilterSelectedOnly", + "d_FilterSelectedOnly@2x","d_forward","d_forward@2x","d_GEAR","d_Groove","d_HorizontalSplit", + "d_icon dropdown","d_InspectorLock","d_JointAngularLimits","d_leftBracket","d_Lighting", + "d_LightmapEditor.WindowTitle","d_LookDevCenterLight","d_LookDevCenterLight@2x","d_LookDevClose", + "d_LookDevClose@2x","d_LookDevEnvRotation","d_LookDevEnvRotation@2x","d_LookDevMirrorViews", + "d_LookDevMirrorViews@2x","d_LookDevMirrorViewsActive","d_LookDevMirrorViewsActive@2x", + "d_LookDevMirrorViewsInactive","d_LookDevMirrorViewsInactive@2x","d_LookDevObjRotation", + "d_LookDevObjRotation@2x","d_LookDevPaneOption","d_LookDevPaneOption@2x","d_LookDevResetEnv", + "d_LookDevResetEnv@2x","d_LookDevShadow","d_LookDevShadow@2x","d_LookDevSideBySide", + "d_LookDevSideBySide@2x","d_LookDevSingle1","d_LookDevSingle1@2x","d_LookDevSingle2", + "d_LookDevSingle2@2x","d_LookDevSplit","d_LookDevSplit@2x","d_LookDevZone","d_LookDevZone@2x", + "d_Mirror","d_model large","d_monologo","d_MoveTool on","d_MoveTool","d_Navigation","d_Occlusion", + "d_P4_AddedLocal","d_P4_AddedRemote","d_P4_CheckOutLocal","d_P4_CheckOutRemote","d_P4_Conflicted", + "d_P4_DeletedLocal","d_P4_DeletedRemote","d_P4_Local","d_P4_LockedLocal","d_P4_LockedRemote", + "d_P4_OutOfSync","d_Particle Effect","d_PauseButton On","d_PauseButton","d_PlayButton On","d_PlayButton", + "d_PlayButtonProfile On","d_PlayButtonProfile","d_playLoopOff","d_playLoopOn","d_preAudioAutoPlayOff", + "d_preAudioAutoPlayOn","d_preAudioLoopOff","d_preAudioLoopOn","d_preAudioPlayOff","d_preAudioPlayOn", + "d_PreMatCube","d_PreMatCylinder","d_PreMatLight0","d_PreMatLight1","d_PreMatSphere","d_PreMatTorus", + "d_Preset.Context","d_PreTextureAlpha","d_PreTextureMipMapHigh","d_PreTextureMipMapLow","d_PreTextureRGB", + "d_Profiler.Audio","d_Profiler.CPU","d_Profiler.FirstFrame","d_Profiler.GPU","d_Profiler.LastFrame", + "d_Profiler.Memory","d_Profiler.Network","d_Profiler.NextFrame","d_Profiler.Physics","d_Profiler.PrevFrame", + "d_Profiler.Record","d_Profiler.Rendering","d_Profiler.Video","d_ProfilerColumn.WarningCount","d_Project", + "d_RectTool On","d_RectTool","d_RectTransformBlueprint","d_RectTransformRaw","d_redGroove","d_Refresh", + "d_renderdoc","d_rightBracket","d_RotateTool On","d_RotateTool","d_ScaleTool On","d_ScaleTool", + "d_SceneViewAlpha","d_SceneViewAudio","d_SceneViewFx","d_SceneViewLighting","d_SceneViewOrtho", + "d_SceneViewRGB","d_ScrollShadow","d_Settings","d_SettingsIcon","d_SocialNetworks.FacebookShare", + "d_SocialNetworks.LinkedInShare","d_SocialNetworks.Tweet","d_SocialNetworks.UDNOpen","d_SpeedScale", + "d_StepButton On","d_StepButton","d_StepLeftButton-On","d_StepLeftButton","d_SVN_AddedLocal", + "d_SVN_Conflicted","d_SVN_DeletedLocal","d_SVN_Local","d_SVN_LockedLocal","d_SVN_OutOfSync","d_tab_next", + "d_tab_next@2x","d_tab_prev","d_tab_prev@2x","d_TerrainInspector.TerrainToolLower On", + "d_TerrainInspector.TerrainToolLowerAlt","d_TerrainInspector.TerrainToolPlants On", + "d_TerrainInspector.TerrainToolPlants","d_TerrainInspector.TerrainToolPlantsAlt On", + "d_TerrainInspector.TerrainToolPlantsAlt","d_TerrainInspector.TerrainToolRaise On", + "d_TerrainInspector.TerrainToolRaise","d_TerrainInspector.TerrainToolSetheight On", + "d_TerrainInspector.TerrainToolSetheight","d_TerrainInspector.TerrainToolSetheightAlt On", + "d_TerrainInspector.TerrainToolSetheightAlt","d_TerrainInspector.TerrainToolSettings On", + "d_TerrainInspector.TerrainToolSettings","d_TerrainInspector.TerrainToolSmoothHeight On", + "d_TerrainInspector.TerrainToolSmoothHeight","d_TerrainInspector.TerrainToolSplat On", + "d_TerrainInspector.TerrainToolSplat","d_TerrainInspector.TerrainToolSplatAlt On", + "d_TerrainInspector.TerrainToolSplatAlt","d_TerrainInspector.TerrainToolTrees On", + "d_TerrainInspector.TerrainToolTrees","d_TerrainInspector.TerrainToolTreesAlt On", + "d_TerrainInspector.TerrainToolTreesAlt","d_TimelineDigIn","d_TimelineEditModeMixOFF", + "d_TimelineEditModeMixON","d_TimelineEditModeReplaceOFF","d_TimelineEditModeReplaceON", + "d_TimelineEditModeRippleOFF","d_TimelineEditModeRippleON","d_TimelineSelector","d_Toolbar Minus", + "d_Toolbar Plus More","d_Toolbar Plus","d_ToolHandleCenter","d_ToolHandleGlobal","d_ToolHandleLocal", + "d_ToolHandlePivot","d_tranp","d_TransformTool On","d_TransformTool","d_tree_icon","d_tree_icon_branch", + "d_tree_icon_branch_frond","d_tree_icon_frond","d_tree_icon_leaf","d_TreeEditor.AddBranches", + "d_TreeEditor.AddLeaves","d_TreeEditor.Branch On","d_TreeEditor.Branch","d_TreeEditor.BranchFreeHand On", + "d_TreeEditor.BranchFreeHand","d_TreeEditor.BranchRotate On","d_TreeEditor.BranchRotate", + "d_TreeEditor.BranchScale On","d_TreeEditor.BranchScale","d_TreeEditor.BranchTranslate On", + "d_TreeEditor.BranchTranslate","d_TreeEditor.Distribution On","d_TreeEditor.Distribution", + "d_TreeEditor.Duplicate","d_TreeEditor.Geometry On","d_TreeEditor.Geometry","d_TreeEditor.Leaf On", + "d_TreeEditor.Leaf","d_TreeEditor.LeafFreeHand On","d_TreeEditor.LeafFreeHand","d_TreeEditor.LeafRotate On", + "d_TreeEditor.LeafRotate","d_TreeEditor.LeafScale On","d_TreeEditor.LeafScale", + "d_TreeEditor.LeafTranslate On","d_TreeEditor.LeafTranslate","d_TreeEditor.Material On", + "d_TreeEditor.Material","d_TreeEditor.Refresh","d_TreeEditor.Trash","d_TreeEditor.Wind On", + "d_TreeEditor.Wind","d_UnityEditor.AnimationWindow","d_UnityEditor.ConsoleWindow", + "d_UnityEditor.DebugInspectorWindow","d_UnityEditor.FindDependencies","d_UnityEditor.GameView", + "d_UnityEditor.HierarchyWindow","d_UnityEditor.InspectorWindow","d_UnityEditor.LookDevView", + "d_UnityEditor.ProfilerWindow","d_UnityEditor.SceneHierarchyWindow","d_UnityEditor.SceneView", + "d_UnityEditor.Timeline.TimelineWindow","d_UnityEditor.VersionControl","d_UnityLogo","d_VerticalSplit", + "d_ViewToolMove On","d_ViewToolMove","d_ViewToolOrbit On","d_ViewToolOrbit","d_ViewToolZoom On", + "d_ViewToolZoom","d_VisibilityOff","d_VisibilityOn","d_VUMeterTextureHorizontal","d_VUMeterTextureVertical", + "d_WaitSpin00","d_WaitSpin01","d_WaitSpin02","d_WaitSpin03","d_WaitSpin04","d_WaitSpin05","d_WaitSpin06", + "d_WaitSpin07","d_WaitSpin08","d_WaitSpin09","d_WaitSpin10","d_WaitSpin11","d_WelcomeScreen.AssetStoreLogo", + "d_winbtn_graph","d_winbtn_graph_close_h","d_winbtn_graph_max_h","d_winbtn_graph_min_h", + "d_winbtn_mac_close","d_winbtn_mac_close_a","d_winbtn_mac_close_h","d_winbtn_mac_inact","d_winbtn_mac_max", + "d_winbtn_mac_max_a","d_winbtn_mac_max_h","d_winbtn_mac_min","d_winbtn_mac_min_a","d_winbtn_mac_min_h", + "d_winbtn_win_close","d_winbtn_win_close_a","d_winbtn_win_close_h","d_winbtn_win_max","d_winbtn_win_max_a", + "d_winbtn_win_max_h","d_winbtn_win_min","d_winbtn_win_min_a","d_winbtn_win_min_h","d_winbtn_win_rest", + "d_winbtn_win_rest_a","d_winbtn_win_rest_h","DefaultSorting","EditCollider","editcollision_16", + "editconstraints_16","editicon.sml","endButton-On","endButton","eyeDropper.Large","eyeDropper.sml", + "Favorite","FilterByLabel","FilterByType","FilterSelectedOnly","FilterSelectedOnly@2x","forward", + "forward@2x","GEAR","Grid.BoxTool","Grid.Default","Grid.EraserTool","Grid.FillTool","Grid.MoveTool", + "Grid.PaintTool","Grid.PickingTool","Grid.SelectTool","Groove","align_horizontally", + "align_horizontally_center","align_horizontally_center_active","align_horizontally_left", + "align_horizontally_left_active","align_horizontally_right","align_horizontally_right_active", + "align_vertically","align_vertically_bottom","align_vertically_bottom_active","align_vertically_center", + "align_vertically_center_active","align_vertically_top","align_vertically_top_active", + "d_align_horizontally","d_align_horizontally_center","d_align_horizontally_center_active", + "d_align_horizontally_left","d_align_horizontally_left_active","d_align_horizontally_right", + "d_align_horizontally_right_active","d_align_vertically","d_align_vertically_bottom", + "d_align_vertically_bottom_active","d_align_vertically_center","d_align_vertically_center_active", + "d_align_vertically_top","d_align_vertically_top_active","HorizontalSplit","icon dropdown", + "InspectorLock","JointAngularLimits","KnobCShape","KnobCShapeMini","leftBracket","Lighting", + "LightmapEditor.WindowTitle","Lightmapping","d_greenLight","d_lightOff","d_lightRim","d_orangeLight", + "d_redLight","greenLight","lightOff","lightRim","orangeLight","redLight","LockIcon-On","LockIcon", + "LookDevCenterLight","LookDevCenterLightl@2x","LookDevClose","LookDevClose@2x","LookDevEnvRotation", + "LookDevEnvRotation@2x","LookDevEyedrop","LookDevLight","LookDevLight@2x","LookDevMirrorViewsActive", + "LookDevMirrorViewsActive@2x","LookDevMirrorViewsInactive","LookDevMirrorViewsInactive@2x", + "LookDevObjRotation","LookDevObjRotation@2x","LookDevPaneOption","LookDevPaneOption@2x","LookDevResetEnv", + "LookDevResetEnv@2x","LookDevShadow","LookDevShadow@2x","LookDevShadowFrame","LookDevShadowFrame@2x", + "LookDevSideBySide","LookDevSideBySide@2x","LookDevSingle1","LookDevSingle1@2x","LookDevSingle2", + "LookDevSingle2@2x","LookDevSplit","LookDevSplit@2x","LookDevZone","LookDevZone@2x","loop","Mirror", + "monologo","MoveTool on","MoveTool","Navigation","Occlusion","P4_AddedLocal","P4_AddedRemote", + "P4_BlueLeftParenthesis","P4_BlueRightParenthesis","P4_CheckOutLocal","P4_CheckOutRemote","P4_Conflicted", + "P4_DeletedLocal","P4_DeletedRemote","P4_Local","P4_LockedLocal","P4_LockedRemote","P4_OutOfSync", + "P4_RedLeftParenthesis","P4_RedRightParenthesis","P4_Updating","PackageBadgeDelete","PackageBadgeNew", + "Particle Effect","PauseButton On","PauseButton","PlayButton On","PlayButton","PlayButtonProfile On", + "PlayButtonProfile","playLoopOff","playLoopOn","playSpeed","preAudioAutoPlayOff","preAudioAutoPlayOn", + "preAudioLoopOff","preAudioLoopOn","preAudioPlayOff","preAudioPlayOn","PreMatCube","PreMatCylinder", + "PreMatLight0","PreMatLight1","PreMatQuad","PreMatSphere","PreMatTorus","Preset.Context","PreTextureAlpha", + "PreTextureArrayFirstSlice","PreTextureArrayLastSlice","PreTextureMipMapHigh","PreTextureMipMapLow", + "PreTextureRGB","AreaLight Gizmo","AreaLight Icon","Assembly Icon","AssetStore Icon","AudioMixerView Icon", + "AudioSource Gizmo","Camera Gizmo","CGProgram Icon","ChorusFilter Icon","CollabChanges Icon", + "CollabChangesConflict Icon","CollabChangesDeleted Icon","CollabConflict Icon","CollabCreate Icon", + "CollabDeleted Icon","CollabEdit Icon","CollabExclude Icon","CollabMoved Icon","cs Script Icon", + "d_AudioMixerView Icon","d_CollabChanges Icon","d_CollabChangesConflict Icon","d_CollabChangesDeleted Icon", + "d_CollabConflict Icon","d_CollabCreate Icon","d_CollabDeleted Icon","d_CollabEdit Icon", + "d_CollabExclude Icon","d_CollabMoved Icon","d_GridLayoutGroup Icon","d_HorizontalLayoutGroup Icon", + "d_Prefab Icon","d_PrefabModel Icon","d_PrefabVariant Icon","d_VerticalLayoutGroup Icon", + "DefaultSlate Icon","DirectionalLight Gizmo","DirectionalLight Icon","DiscLight Gizmo","DiscLight Icon", + "dll Script Icon","EchoFilter Icon","Favorite Icon","Folder Icon","FolderEmpty Icon", + "FolderFavorite Icon","GameManager Icon","GridBrush Icon","HighPassFilter Icon", + "HorizontalLayoutGroup Icon","LensFlare Gizmo","LightingDataAssetParent Icon","LightProbeGroup Gizmo", + "LightProbeProxyVolume Gizmo","LowPassFilter Icon","Main Light Gizmo","MetaFile Icon", + "Microphone Icon","MuscleClip Icon","ParticleSystem Gizmo","PointLight Gizmo","Prefab Icon", + "PrefabModel Icon","PrefabOverlayAdded Icon","PrefabOverlayModified Icon","PrefabOverlayRemoved Icon", + "PrefabVariant Icon","Projector Gizmo","RaycastCollider Icon","ReflectionProbe Gizmo", + "ReverbFilter Icon","SceneSet Icon","Search Icon","SoftlockProjectBrowser Icon","SpeedTreeModel Icon", + "SpotLight Gizmo","Spotlight Icon","SpriteCollider Icon","sv_icon_dot0_pix16_gizmo", + "sv_icon_dot10_pix16_gizmo","sv_icon_dot11_pix16_gizmo","sv_icon_dot12_pix16_gizmo", + "sv_icon_dot13_pix16_gizmo","sv_icon_dot14_pix16_gizmo","sv_icon_dot15_pix16_gizmo", + "sv_icon_dot1_pix16_gizmo","sv_icon_dot2_pix16_gizmo","sv_icon_dot3_pix16_gizmo", + "sv_icon_dot4_pix16_gizmo","sv_icon_dot5_pix16_gizmo","sv_icon_dot6_pix16_gizmo", + "sv_icon_dot7_pix16_gizmo","sv_icon_dot8_pix16_gizmo","sv_icon_dot9_pix16_gizmo", + "AnimatorController Icon","AnimatorState Icon","AnimatorStateMachine Icon", + "AnimatorStateTransition Icon","BlendTree Icon","AnimationWindowEvent Icon","AudioMixerController Icon", + "DefaultAsset Icon","EditorSettings Icon","AnyStateNode Icon","HumanTemplate Icon", + "LightingDataAsset Icon","LightmapParameters Icon","Preset Icon","SceneAsset Icon", + "SubstanceArchive Icon","AssemblyDefinitionAsset Icon","NavMeshAgent Icon","NavMeshData Icon", + "NavMeshObstacle Icon","OffMeshLink Icon","AnalyticsTracker Icon","Animation Icon", + "AnimationClip Icon","AimConstraint Icon","d_AimConstraint Icon","d_LookAtConstraint Icon", + "d_ParentConstraint Icon","d_PositionConstraint Icon","d_RotationConstraint Icon", + "d_ScaleConstraint Icon","LookAtConstraint Icon","ParentConstraint Icon","PositionConstraint Icon", + "RotationConstraint Icon","ScaleConstraint Icon","Animator Icon","AnimatorOverrideController Icon", + "AreaEffector2D Icon","AudioMixerGroup Icon","AudioMixerSnapshot Icon","AudioSpatializerMicrosoft Icon", + "AudioChorusFilter Icon","AudioClip Icon","AudioDistortionFilter Icon","AudioEchoFilter Icon", + "AudioHighPassFilter Icon","AudioListener Icon","AudioLowPassFilter Icon","AudioReverbFilter Icon", + "AudioReverbZone Icon","AudioSource Icon","Avatar Icon","AvatarMask Icon","BillboardAsset Icon", + "BillboardRenderer Icon","BoxCollider Icon","BoxCollider2D Icon","BuoyancyEffector2D Icon","Camera Icon", + "Canvas Icon","CanvasGroup Icon","CanvasRenderer Icon","CapsuleCollider Icon","CapsuleCollider2D Icon", + "CharacterController Icon","CharacterJoint Icon","CircleCollider2D Icon","Cloth Icon", + "CompositeCollider2D Icon","ComputeShader Icon","ConfigurableJoint Icon","ConstantForce Icon", + "ConstantForce2D Icon","Cubemap Icon","d_Canvas Icon","d_CanvasGroup Icon","d_CanvasRenderer Icon", + "d_GameObject Icon","d_LightProbeProxyVolume Icon","d_ParticleSystem Icon","d_ParticleSystemForceField Icon", + "d_RectTransform Icon","d_StreamingController Icon","DistanceJoint2D Icon","EdgeCollider2D Icon", + "d_EventSystem Icon","d_EventTrigger Icon","d_Physics2DRaycaster Icon","d_PhysicsRaycaster Icon", + "d_StandaloneInputModule Icon","d_TouchInputModule Icon","EventSystem Icon","EventTrigger Icon", + "HoloLensInputModule Icon","Physics2DRaycaster Icon","PhysicsRaycaster Icon","StandaloneInputModule Icon", + "TouchInputModule Icon","SpriteShapeRenderer Icon","VisualTreeAsset Icon","d_VisualEffect Icon", + "d_VisualEffectAsset Icon","VisualEffect Icon","VisualEffectAsset Icon","FixedJoint Icon", + "FixedJoint2D Icon","Flare Icon","FlareLayer Icon","Font Icon","FrictionJoint2D Icon", + "GameObject Icon","Grid Icon","GUILayer Icon","GUISkin Icon","GUIText Icon","GUITexture Icon", + "Halo Icon","HingeJoint Icon","HingeJoint2D Icon","LensFlare Icon","Light Icon","LightProbeGroup Icon", + "LightProbeProxyVolume Icon","LightProbes Icon","LineRenderer Icon","LODGroup Icon","Material Icon", + "Mesh Icon","MeshCollider Icon","MeshFilter Icon","MeshRenderer Icon","Motion Icon","MovieTexture Icon", + "NetworkAnimator Icon","NetworkDiscovery Icon","NetworkIdentity Icon","NetworkLobbyManager Icon", + "NetworkLobbyPlayer Icon","NetworkManager Icon","NetworkManagerHUD Icon","NetworkMigrationManager Icon", + "NetworkProximityChecker Icon","NetworkStartPosition Icon","NetworkTransform Icon", + "NetworkTransformChild Icon","NetworkTransformVisualizer Icon","NetworkView Icon","OcclusionArea Icon", + "OcclusionPortal Icon","ParticleSystem Icon","ParticleSystemForceField Icon","PhysicMaterial Icon", + "PhysicsMaterial2D Icon","PlatformEffector2D Icon","d_PlayableDirector Icon","PlayableDirector Icon", + "PointEffector2D Icon","PolygonCollider2D Icon","ProceduralMaterial Icon","Projector Icon", + "RectTransform Icon","ReflectionProbe Icon","RelativeJoint2D Icon","d_SortingGroup Icon", + "SortingGroup Icon","RenderTexture Icon","Rigidbody Icon","Rigidbody2D Icon","ScriptableObject Icon", + "Shader Icon","ShaderVariantCollection Icon","SkinnedMeshRenderer Icon","Skybox Icon","SliderJoint2D Icon", + "TrackedPoseDriver Icon","SphereCollider Icon","SpringJoint Icon","SpringJoint2D Icon","Sprite Icon", + "SpriteMask Icon","SpriteRenderer Icon","StreamingController Icon","StyleSheet Icon","SurfaceEffector2D Icon", + "TargetJoint2D Icon","Terrain Icon","TerrainCollider Icon","TerrainData Icon","TextAsset Icon", + "TextMesh Icon","Texture Icon","Texture2D Icon","Tile Icon","Tilemap Icon","TilemapCollider2D Icon", + "TilemapRenderer Icon","d_TimelineAsset Icon","TimelineAsset Icon","TrailRenderer Icon","Transform Icon", + "SpriteAtlas Icon","AspectRatioFitter Icon","Button Icon","CanvasScaler Icon","ContentSizeFitter Icon", + "d_AspectRatioFitter Icon","d_CanvasScaler Icon","d_ContentSizeFitter Icon","d_FreeformLayoutGroup Icon", + "d_GraphicRaycaster Icon","d_GridLayoutGroup Icon","d_HorizontalLayoutGroup Icon","d_LayoutElement Icon", + "d_PhysicalResolution Icon","d_ScrollViewArea Icon","d_SelectionList Icon","d_SelectionListItem Icon", + "d_SelectionListTemplate Icon","d_VerticalLayoutGroup Icon","Dropdown Icon","FreeformLayoutGroup Icon", + "GraphicRaycaster Icon","GridLayoutGroup Icon","HorizontalLayoutGroup Icon","Image Icon","InputField Icon", + "LayoutElement Icon","Mask Icon","Outline Icon","PositionAsUV1 Icon","RawImage Icon","RectMask2D Icon", + "Scrollbar Icon","ScrollRect Icon","Selectable Icon","Shadow Icon","Slider Icon","Text Icon","Toggle Icon", + "ToggleGroup Icon","VerticalLayoutGroup Icon","VideoClip Icon","VideoPlayer Icon","VisualEffect Icon", + "VisualEffectAsset Icon","WheelCollider Icon","WheelJoint2D Icon","WindZone Icon", + "SpatialMappingCollider Icon","SpatialMappingRenderer Icon","WorldAnchor Icon","UssScript Icon", + "UxmlScript Icon","VerticalLayoutGroup Icon","VideoEffect Icon","VisualEffect Gizmo", + "VisualEffectAsset Icon","AnchorBehaviour Icon","AnchorInputListenerBehaviour Icon", + "AnchorStageBehaviour Icon","CloudRecoBehaviour Icon","ContentPlacementBehaviour Icon", + "ContentPositioningBehaviour Icon","CylinderTargetBehaviour Icon","d_AnchorBehaviour Icon", + "d_AnchorInputListenerBehaviour Icon","d_AnchorStageBehaviour Icon","d_CloudRecoBehaviour Icon", + "d_ContentPlacementBehaviour Icon","d_ContentPositioningBehaviour Icon","d_CylinderTargetBehaviour Icon", + "d_ImageTargetBehaviour Icon","d_MidAirPositionerBehaviour Icon","d_ModelTargetBehaviour Icon", + "d_MultiTargetBehaviour Icon","d_ObjectTargetBehaviour Icon","d_PlaneFinderBehaviour Icon", + "d_UserDefinedTargetBuildingBehaviour Icon","d_VirtualButtonBehaviour Icon","d_VuforiaBehaviour Icon", + "d_VuMarkBehaviour Icon","d_WireframeBehaviour Icon","ImageTargetBehaviour Icon", + "MidAirPositionerBehaviour Icon","ModelTargetBehaviour Icon","MultiTargetBehaviour Icon", + "ObjectTargetBehaviour Icon","PlaneFinderBehaviour Icon","UserDefinedTargetBuildingBehaviour Icon", + "VirtualButtonBehaviour Icon","VuforiaBehaviour Icon","VuMarkBehaviour Icon","WireframeBehaviour Icon", + "WindZone Gizmo","Profiler.Audio","Profiler.CPU","Profiler.FirstFrame","Profiler.GlobalIllumination", + "Profiler.GPU","Profiler.Instrumentation","Profiler.LastFrame","Profiler.Memory","Profiler.NetworkMessages", + "Profiler.NetworkOperations","Profiler.NextFrame","Profiler.Physics","Profiler.Physics2D", + "Profiler.PrevFrame","Profiler.Record","Profiler.Rendering","Profiler.UI","Profiler.UIDetails", + "Profiler.Video","ProfilerColumn.WarningCount","Project","RectTool On","RectTool","RectTransformBlueprint", + "RectTransformRaw","redGroove","Refresh","renderdoc","rightBracket","RotateTool On","RotateTool", + "SaveActive","SaveFromPlay","SavePassive","ScaleTool On","ScaleTool","SceneLoadIn","SceneLoadOut", + "SceneSave","SceneSaveGrey","SceneViewAlpha","SceneViewAudio","SceneViewFx","SceneViewLighting", + "SceneViewOrtho","SceneViewRGB","ScrollShadow","Settings","SettingsIcon","SocialNetworks.FacebookShare", + "SocialNetworks.LinkedInShare","SocialNetworks.Tweet","SocialNetworks.UDNLogo","SocialNetworks.UDNOpen", + "SoftlockInline","SpeedScale","StateMachineEditor.ArrowTip","StateMachineEditor.ArrowTipSelected", + "StateMachineEditor.Background","StateMachineEditor.State","StateMachineEditor.StateHover", + "StateMachineEditor.StateSelected","StateMachineEditor.StateSub","StateMachineEditor.StateSubHover", + "StateMachineEditor.StateSubSelected","StateMachineEditor.UpButton","StateMachineEditor.UpButtonHover", + "StepButton On","StepButton","StepLeftButton-On","StepLeftButton","sticky_arrow","sticky_p4","sticky_skin", + "sv_icon_dot0_sml","sv_icon_dot10_sml","sv_icon_dot11_sml","sv_icon_dot12_sml","sv_icon_dot13_sml", + "sv_icon_dot14_sml","sv_icon_dot15_sml","sv_icon_dot1_sml","sv_icon_dot2_sml","sv_icon_dot3_sml", + "sv_icon_dot4_sml","sv_icon_dot5_sml","sv_icon_dot6_sml","sv_icon_dot7_sml","sv_icon_dot8_sml", + "sv_icon_dot9_sml","sv_icon_name0","sv_icon_name1","sv_icon_name2","sv_icon_name3","sv_icon_name4", + "sv_icon_name5","sv_icon_name6","sv_icon_name7","sv_icon_none","sv_label_0","sv_label_1","sv_label_2", + "sv_label_3","sv_label_4","sv_label_5","sv_label_6","sv_label_7","SVN_AddedLocal","SVN_Conflicted", + "SVN_DeletedLocal","SVN_Local","SVN_LockedLocal","SVN_OutOfSync","tab_next","tab_next@2x","tab_prev", + "tab_prev@2x","TerrainInspector.TerrainToolLower On","TerrainInspector.TerrainToolLower", + "TerrainInspector.TerrainToolLowerAlt","TerrainInspector.TerrainToolPlants On", + "TerrainInspector.TerrainToolPlants","TerrainInspector.TerrainToolPlantsAlt On", + "TerrainInspector.TerrainToolPlantsAlt","TerrainInspector.TerrainToolRaise On", + "TerrainInspector.TerrainToolRaise","TerrainInspector.TerrainToolSculpt On", + "TerrainInspector.TerrainToolSculpt","TerrainInspector.TerrainToolSetheight On", + "TerrainInspector.TerrainToolSetheight","TerrainInspector.TerrainToolSetheightAlt On", + "TerrainInspector.TerrainToolSetheightAlt","TerrainInspector.TerrainToolSettings On", + "TerrainInspector.TerrainToolSettings","TerrainInspector.TerrainToolSmoothHeight On", + "TerrainInspector.TerrainToolSmoothHeight","TerrainInspector.TerrainToolSplat On", + "TerrainInspector.TerrainToolSplat","TerrainInspector.TerrainToolSplatAlt On", + "TerrainInspector.TerrainToolSplatAlt","TerrainInspector.TerrainToolTrees On", + "TerrainInspector.TerrainToolTrees","TerrainInspector.TerrainToolTreesAlt On", + "TerrainInspector.TerrainToolTreesAlt","TestFailed","TestIgnored","TestInconclusive","TestNormal", + "TestPassed","TestStopwatch","TimelineClipBG","TimelineClipFG","TimelineDigIn","TimelineEditModeMixOFF", + "TimelineEditModeMixON","TimelineEditModeReplaceOFF","TimelineEditModeReplaceON","TimelineEditModeRippleOFF", + "TimelineEditModeRippleON","TimelineSelector","Toolbar Minus","Toolbar Plus More","Toolbar Plus", + "ToolHandleCenter","ToolHandleGlobal","ToolHandleLocal","ToolHandlePivot","tranp","TransformTool On", + "TransformTool","tree_icon","tree_icon_branch","tree_icon_branch_frond","tree_icon_frond","tree_icon_leaf", + "TreeEditor.AddBranches","TreeEditor.AddLeaves","TreeEditor.Branch On","TreeEditor.Branch", + "TreeEditor.BranchFreeHand On","TreeEditor.BranchFreeHand","TreeEditor.BranchRotate On", + "TreeEditor.BranchRotate","TreeEditor.BranchScale On","TreeEditor.BranchScale", + "TreeEditor.BranchTranslate On","TreeEditor.BranchTranslate","TreeEditor.Distribution On", + "TreeEditor.Distribution","TreeEditor.Duplicate","TreeEditor.Geometry On","TreeEditor.Geometry", + "TreeEditor.Leaf On","TreeEditor.Leaf","TreeEditor.LeafFreeHand On","TreeEditor.LeafFreeHand", + "TreeEditor.LeafRotate On","TreeEditor.LeafRotate","TreeEditor.LeafScale On","TreeEditor.LeafScale", + "TreeEditor.LeafTranslate On","TreeEditor.LeafTranslate","TreeEditor.Material On","TreeEditor.Material", + "TreeEditor.Refresh","TreeEditor.Trash","TreeEditor.Wind On","TreeEditor.Wind","UnityEditor.AnimationWindow", + "UnityEditor.ConsoleWindow","UnityEditor.DebugInspectorWindow","UnityEditor.FindDependencies", + "UnityEditor.GameView","UnityEditor.Graphs.AnimatorControllerTool","UnityEditor.HierarchyWindow", + "UnityEditor.InspectorWindow","UnityEditor.LookDevView","UnityEditor.ProfilerWindow", + "UnityEditor.SceneHierarchyWindow","UnityEditor.SceneView","UnityEditor.Timeline.TimelineWindow", + "UnityEditor.VersionControl","UnityLogo","UnityLogoLarge","UpArrow","vcs_add","vcs_branch","vcs_change", + "vcs_check","vcs_delete","vcs_document","vcs_edit","vcs_incoming","vcs_integrate","vcs_local","vcs_lock", + "vcs_refresh","vcs_sync","vcs_unresolved","vcs_update","VerticalSplit","ViewToolMove On","ViewToolMove", + "ViewToolOrbit On","ViewToolOrbit","ViewToolZoom On","ViewToolZoom","VisibilityOff","VisibilityOn", + "VisualEffect Gizmo","VUMeterTextureHorizontal","VUMeterTextureVertical","WaitSpin00","WaitSpin01", + "WaitSpin02","WaitSpin03","WaitSpin04","WaitSpin05","WaitSpin06","WaitSpin07","WaitSpin08","WaitSpin09", + "WaitSpin10","WaitSpin11","WelcomeScreen.AssetStoreLogo","winbtn_graph","winbtn_graph_close_h", + "winbtn_graph_max_h","winbtn_graph_min_h","winbtn_mac_close","winbtn_mac_close_a","winbtn_mac_close_h", + "winbtn_mac_inact","winbtn_mac_max","winbtn_mac_max_a","winbtn_mac_max_h","winbtn_mac_min", + "winbtn_mac_min_a","winbtn_mac_min_h","winbtn_win_close","winbtn_win_close_a","winbtn_win_close_h", + "winbtn_win_max","winbtn_win_max_a","winbtn_win_max_h","winbtn_win_min","winbtn_win_min_a", + "winbtn_win_min_h","winbtn_win_rest","winbtn_win_rest_a","winbtn_win_rest_h", + "AvatarInspector/RightFingersIk","AvatarInspector/LeftFingersIk","AvatarInspector/RightFeetIk", + "AvatarInspector/LeftFeetIk","AvatarInspector/RightFingers","AvatarInspector/LeftFingers", + "AvatarInspector/RightArm","AvatarInspector/LeftArm","AvatarInspector/RightLeg","AvatarInspector/LeftLeg", + "AvatarInspector/Head","AvatarInspector/Torso","AvatarInspector/MaskEditor_Root", + "AvatarInspector/BodyPartPicker","AvatarInspector/BodySIlhouette","boo Script Icon","js Script Icon", + "EyeDropper.Large","AboutWindow.MainHeader","AgeiaLogo","MonoLogo","PlayButtonProfile Anim", + "StepButton Anim","PauseButton Anim","PlayButton Anim","MoveTool On","Icon Dropdown", + "AvatarInspector/DotSelection","AvatarInspector/DotFrameDotted","AvatarInspector/DotFrame", + "AvatarInspector/DotFill","AvatarInspector/RightHandZoom","AvatarInspector/LeftHandZoom", + "AvatarInspector/HeadZoom","AvatarInspector/RightLeg","AvatarInspector/LeftLeg", + "AvatarInspector/RightFingers","AvatarInspector/RightArm","AvatarInspector/LeftFingers", + "AvatarInspector/LeftArm","AvatarInspector/Head","AvatarInspector/Torso", + "AvatarInspector/RightHandZoomSilhouette","AvatarInspector/LeftHandZoomSilhouette", + "AvatarInspector/HeadZoomSilhouette","AvatarInspector/BodySilhouette","lightMeter/redLight", + "lightMeter/orangeLight","lightMeter/lightRim","lightMeter/greenLight","SceneviewAudio", + "SceneviewLighting","TerrainInspector.TerrainToolSetHeight","AS Badge New","AS Badge Move", + "AS Badge Delete","WelcomeScreen.UnityAnswersLogo","WelcomeScreen.UnityForumLogo", + "WelcomeScreen.UnityBasicsLogo","WelcomeScreen.VideoTutLogo","WelcomeScreen.MainHeader","Icon Dropdown", + "PrefabNormal Icon","PrefabNormal Icon","BuildSettings.BlackBerry.Small","BuildSettings.Tizen.Small", + "BuildSettings.XBox360.Small","BuildSettings.PS3.Small","BuildSettings.SamsungTV.Small", + "BuildSettings.BlackBerry","BuildSettings.Tizen","BuildSettings.XBox360","BuildSettings.PS3", + "BuildSettings.SamsungTV" + }; + + #endregion +} +#endif \ No newline at end of file diff --git a/Editor/EditorIcons.cs.meta b/Editor/EditorIcons.cs.meta new file mode 100644 index 0000000..2d10dc1 --- /dev/null +++ b/Editor/EditorIcons.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: afdf034c3cbaaf34287f7bd5fa6d7474 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/EditorToolFunctionAttribute.cs b/Editor/EditorToolFunctionAttribute.cs new file mode 100644 index 0000000..b818efb --- /dev/null +++ b/Editor/EditorToolFunctionAttribute.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; + +namespace AlicizaX.Editor.Extension +{ + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] + public class EditorToolFunctionAttribute : Attribute + { + public string ToolMenuPath { get; private set; } + public int MenuOrder { get; private set; } + public MethodInfo MethodInfo { get; private set; } + + public EditorToolFunctionAttribute(string menu, int menuOrder = 0) + { + this.ToolMenuPath = menu; + MenuOrder = menuOrder; + } + + public void SetMethodInfo(MethodInfo methodInfo) + { + MethodInfo = methodInfo; + } + } + + internal static class EditorToolFunctionAttributeCollector + { + public static List Attributes = new List(); + + static void Register(EditorToolFunctionAttribute attribute) + { + Attributes.Add(attribute); + Attributes.Sort((x, y) => x.MenuOrder.CompareTo(y.MenuOrder)); + } + + /// + /// 扫描所有程序集中的类和方法,自动注册带有 EditorToolFunctionAttribute 的方法。 + /// + [InitializeOnLoadMethod] + static void ScanAndRegisterAllMethods() + { + // 获取当前应用程序域中的所有程序集 + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + + foreach (var assembly in assemblies) + { + try + { + // 获取程序集中的所有类型 + var types = assembly.GetTypes(); + + foreach (var type in types) + { + try + { + // 获取类型中的所有方法 + var methods = + type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + + foreach (var method in methods) + { + // 检查方法是否带有 EditorToolFunctionAttribute + var attribute = method.GetCustomAttribute(); + if (attribute != null) + { + // 设置方法的 MethodInfo + attribute.SetMethodInfo(method); + Register(attribute); + } + } + } + catch (Exception ex) + { + Debug.LogError($"Failed to process type {type.FullName}: {ex.Message}"); + } + } + } + catch (Exception ex) + { + Debug.LogError($"Failed to process assembly {assembly.FullName}: {ex.Message}"); + } + } + + // Debug.Log($"Registered {Attributes.Count} methods with EditorToolFunctionAttribute."); + } + } +} diff --git a/Editor/EditorToolFunctionAttribute.cs.meta b/Editor/EditorToolFunctionAttribute.cs.meta new file mode 100644 index 0000000..cf64513 --- /dev/null +++ b/Editor/EditorToolFunctionAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2ba93c76025575b469a47a345a2636a2 +timeCreated: 1741335052 \ No newline at end of file diff --git a/Plugins.meta b/Editor/Postprocessor.meta similarity index 77% rename from Plugins.meta rename to Editor/Postprocessor.meta index c57f540..9dfdc7c 100644 --- a/Plugins.meta +++ b/Editor/Postprocessor.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 68154f52a1971584ead0467fcd6bd806 +guid: 88285b35731e9e340a5982c056cb7d8e folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Editor/Postprocessor/Atlas.meta b/Editor/Postprocessor/Atlas.meta new file mode 100644 index 0000000..f438ca6 --- /dev/null +++ b/Editor/Postprocessor/Atlas.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 16fac2fa602633346b6f45f4362f28f7 +timeCreated: 1738748198 \ No newline at end of file diff --git a/Editor/Postprocessor/Atlas/AtlasConfiguration.cs b/Editor/Postprocessor/Atlas/AtlasConfiguration.cs new file mode 100644 index 0000000..64b75f7 --- /dev/null +++ b/Editor/Postprocessor/Atlas/AtlasConfiguration.cs @@ -0,0 +1,24 @@ +// AtlasConfiguration.cs + +using UnityEditor; +using UnityEngine; + +[FilePath("ProjectSettings/AtlasConfiguration.asset",FilePathAttribute.Location.ProjectFolder)] +public class AtlasConfiguration : ScriptableSingleton +{ + [Header("Directory Settings")] + public string atlasOutputPath = "Assets/Art/Atlas"; + public string rawUIPath = "Assets/Art/UI/Raw"; + public string uiAtlasPath = "Assets/Art/UI/Atlases"; + + [Header("Texture Settings")] + public TextureImporterFormat androidFormat = TextureImporterFormat.ASTC_6x6; + public TextureImporterFormat iosFormat = TextureImporterFormat.ASTC_5x5; + public TextureImporterFormat webglFormat = TextureImporterFormat.ASTC_6x6; + public int compressionQuality = 50; + + [Header("Packing Settings")] + public int padding = 2; + public bool enableRotation = true; + public int blockOffset = 1; +} diff --git a/Editor/Postprocessor/Atlas/AtlasConfiguration.cs.meta b/Editor/Postprocessor/Atlas/AtlasConfiguration.cs.meta new file mode 100644 index 0000000..d78afce --- /dev/null +++ b/Editor/Postprocessor/Atlas/AtlasConfiguration.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f529ff1e114e8ba4cb189f4233102cd5 +timeCreated: 1738748213 \ No newline at end of file diff --git a/Editor/Postprocessor/Atlas/AtlasEditorWindow.cs b/Editor/Postprocessor/Atlas/AtlasEditorWindow.cs new file mode 100644 index 0000000..b4c8b6b --- /dev/null +++ b/Editor/Postprocessor/Atlas/AtlasEditorWindow.cs @@ -0,0 +1,95 @@ +// AtlasEditorWindow.cs + +using AlicizaX.Editor; +using AlicizaX.Editor.Extension; +using UnityEditor; +using UnityEngine; + +public class AtlasEditorWindow : EditorWindow +{ + private const string AtlasProcessorKey = "AtlasProcessorKey"; + + private AtlasConfiguration config; + private Vector2 scrollPos; + private bool useAtlas = false; + + [EditorToolFunction("图集工具")] + public static void ShowWindow() + { + GetWindow("图集打包"); + } + + private void OnEnable() + { + LoadOrCreateConfig(); + useAtlas = ScriptingDefineSymbols.HasScriptingDefineSymbol(BuildTargetGroup.Standalone, AtlasProcessorKey); + } + + private void LoadOrCreateConfig() + { + config = AtlasConfiguration.instance; + } + + private void OnGUI() + { + if (config == null) return; + + + scrollPos = EditorGUILayout.BeginScrollView(scrollPos); + + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Atlas Configuration", EditorStyles.boldLabel); + var useAtlasToggle = EditorGUILayout.Toggle("Enable", useAtlas); + if (useAtlasToggle != useAtlas) + { + if (useAtlas) + { + ScriptingDefineSymbols.AddScriptingDefineSymbol(AtlasProcessorKey); + } + else + { + ScriptingDefineSymbols.RemoveScriptingDefineSymbol(AtlasProcessorKey); + } + } + + DrawConfigurationGUI(); + EditorGUILayout.EndScrollView(); + } + + private void DrawConfigurationGUI() + { + EditorGUI.BeginChangeCheck(); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Paths", EditorStyles.boldLabel); + config.atlasOutputPath = EditorGUILayout.TextField("Atlas Output", config.atlasOutputPath); + config.rawUIPath = EditorGUILayout.TextField("Raw UI Path", config.rawUIPath); + config.uiAtlasPath = EditorGUILayout.TextField("UI Atlas Path", config.uiAtlasPath); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Texture Settings", EditorStyles.boldLabel); + config.androidFormat = (TextureImporterFormat)EditorGUILayout.EnumPopup("Android Format", config.androidFormat); + config.iosFormat = (TextureImporterFormat)EditorGUILayout.EnumPopup("iOS Format", config.iosFormat); + config.webglFormat = (TextureImporterFormat)EditorGUILayout.EnumPopup("WebGL Format", config.webglFormat); + config.compressionQuality = EditorGUILayout.IntSlider("Compression Quality", + config.compressionQuality, 0, 100); + + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Packing Settings", EditorStyles.boldLabel); + config.padding = EditorGUILayout.IntField("Padding", config.padding); + config.enableRotation = EditorGUILayout.Toggle("Enable Rotation", config.enableRotation); + config.blockOffset = EditorGUILayout.IntField("Block Offset", config.blockOffset); + + if (EditorGUI.EndChangeCheck()) + { + EditorUtility.SetDirty(config); + } + + EditorGUILayout.Space(); + if (GUILayout.Button("Force Rebuild All Atlases", GUILayout.Height(30))) + { + AtlasProcessor.ForceRebuildAtlases(config); + } + } +} diff --git a/Editor/Postprocessor/Atlas/AtlasEditorWindow.cs.meta b/Editor/Postprocessor/Atlas/AtlasEditorWindow.cs.meta new file mode 100644 index 0000000..ae06839 --- /dev/null +++ b/Editor/Postprocessor/Atlas/AtlasEditorWindow.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5a0f8acf9a5e4034f9f28fc384c5ce89 +timeCreated: 1738748236 \ No newline at end of file diff --git a/Editor/Postprocessor/Atlas/AtlasPostprocessor.cs b/Editor/Postprocessor/Atlas/AtlasPostprocessor.cs new file mode 100644 index 0000000..fda18bc --- /dev/null +++ b/Editor/Postprocessor/Atlas/AtlasPostprocessor.cs @@ -0,0 +1,38 @@ +#if AtlasProcessorKey +using UnityEditor; +using UnityEngine; + +public class AtlasPostprocessor : AssetPostprocessor +{ + private static AtlasConfiguration config; + + private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, + string[] movedAssets, string[] movedFromAssetPaths) + { + if (config == null) + { + config = AtlasConfiguration.instance; + } + if (config == null) return; + + foreach (var path in importedAssets) HandleAsset(path); + foreach (var path in movedAssets) HandleAsset(path); + foreach (var path in deletedAssets) HandleDeletedAsset(path); + foreach (var path in movedFromAssetPaths) HandleDeletedAsset(path); + } + + private static void HandleAsset(string path) + { + if (path.EndsWith(".png") || path.EndsWith(".jpg")) + { + AtlasProcessor.ProcessSingleSprite(path, config); + } + } + + private static void HandleDeletedAsset(string path) + { + // Handle removed sprites from atlases + // Implementation depends on tracking system + } +} +#endif diff --git a/Editor/Postprocessor/Atlas/AtlasPostprocessor.cs.meta b/Editor/Postprocessor/Atlas/AtlasPostprocessor.cs.meta new file mode 100644 index 0000000..5015164 --- /dev/null +++ b/Editor/Postprocessor/Atlas/AtlasPostprocessor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e5d969d76e1a36445810f61bafc4f7db +timeCreated: 1738748276 \ No newline at end of file diff --git a/Editor/Postprocessor/Atlas/AtlasProcessor.cs b/Editor/Postprocessor/Atlas/AtlasProcessor.cs new file mode 100644 index 0000000..92e4599 --- /dev/null +++ b/Editor/Postprocessor/Atlas/AtlasProcessor.cs @@ -0,0 +1,210 @@ +// AtlasProcessor.cs +using System.Collections.Generic; +using System.IO; +using UnityEditor; +using UnityEditor.U2D; +using UnityEngine; +using UnityEngine.U2D; + +public static class AtlasProcessor +{ + private static readonly HashSet DirtyAtlas = new HashSet(); + private static readonly Dictionary> AtlasContents = + new Dictionary>(); + + public static void ForceRebuildAtlases(AtlasConfiguration config) + { + InitializeAtlasData(config); + ProcessAllSprites(config); + PackAllAtlases(config); + } + + private static void InitializeAtlasData(AtlasConfiguration config) + { + AtlasContents.Clear(); + var atlasGuids = AssetDatabase.FindAssets("t:SpriteAtlas", new[] { config.atlasOutputPath }); + + foreach (var guid in atlasGuids) + { + var path = AssetDatabase.GUIDToAssetPath(guid); + var atlas = AssetDatabase.LoadAssetAtPath(path); + if (atlas == null) continue; + + var atlasName = Path.GetFileNameWithoutExtension(path); + var packed = atlas.GetPackables(); + AtlasContents[atlasName] = new HashSet(); + + foreach (var obj in packed) + { + var assetPath = AssetDatabase.GetAssetPath(obj); + if (!string.IsNullOrEmpty(assetPath)) + { + AtlasContents[atlasName].Add(assetPath); + } + } + } + } + + private static void ProcessAllSprites(AtlasConfiguration config) + { + var allSprites = AssetDatabase.FindAssets("t:Sprite", new[] { config.rawUIPath }); + foreach (var guid in allSprites) + { + var path = AssetDatabase.GUIDToAssetPath(guid); + ProcessSingleSprite(path, config); + } + } + + public static void ProcessSingleSprite(string path, AtlasConfiguration config) + { + if (!path.StartsWith(config.rawUIPath)) return; + + var importer = AssetImporter.GetAtPath(path) as TextureImporter; + if (importer == null) return; + + ConfigureTextureImporter(importer, config); + AddToAtlas(path, config); + } + + private static void ConfigureTextureImporter(TextureImporter importer, AtlasConfiguration config) + { + var changed = false; + var settings = new TextureImporterSettings(); + importer.ReadTextureSettings(settings); + + if (importer.textureType != TextureImporterType.Sprite) + { + importer.textureType = TextureImporterType.Sprite; + changed = true; + } + + if (settings.spriteGenerateFallbackPhysicsShape) + { + settings.spriteGenerateFallbackPhysicsShape = false; + importer.SetTextureSettings(settings); + changed = true; + } + + ApplyPlatformSettings(importer, "Android", config.androidFormat, config); + ApplyPlatformSettings(importer, "iPhone", config.iosFormat, config); + ApplyPlatformSettings(importer, "WebGL", config.webglFormat, config); + + if (changed) importer.SaveAndReimport(); + } + + private static void ApplyPlatformSettings(TextureImporter importer, string platform, + TextureImporterFormat format, AtlasConfiguration config) + { + var settings = importer.GetPlatformTextureSettings(platform); + if (!settings.overridden || settings.format != format || + settings.compressionQuality != config.compressionQuality) + { + settings.overridden = true; + settings.format = format; + settings.compressionQuality = config.compressionQuality; + importer.SetPlatformTextureSettings(settings); + } + } + + private static void AddToAtlas(string spritePath, AtlasConfiguration config) + { + var atlasName = GetAtlasName(spritePath, config); + if (string.IsNullOrEmpty(atlasName)) return; + + if (!AtlasContents.TryGetValue(atlasName, out var paths)) + { + paths = new HashSet(); + AtlasContents[atlasName] = paths; + } + + if (paths.Add(spritePath)) DirtyAtlas.Add(atlasName); + } + + private static string GetAtlasName(string path, AtlasConfiguration config) + { + var relativePath = path.Replace(config.rawUIPath, "").TrimStart('/'); + var directory = Path.GetDirectoryName(relativePath); + return directory?.Replace("/", "_"); + } + + private static void PackAllAtlases(AtlasConfiguration config) + { + foreach (var atlasName in DirtyAtlas) + { + CreateOrUpdateAtlas(atlasName, config); + } + DirtyAtlas.Clear(); + + SpriteAtlasUtility.PackAllAtlases(EditorUserBuildSettings.activeBuildTarget); + AssetDatabase.SaveAssets(); + } + + private static void CreateOrUpdateAtlas(string atlasName, AtlasConfiguration config) + { + if (!System.IO.Directory.Exists(config.atlasOutputPath)) + { + Directory.CreateDirectory(config.atlasOutputPath); + } + var path = $"{config.atlasOutputPath}/{atlasName}.spriteatlas"; + var atlas = AssetDatabase.LoadAssetAtPath(path) ?? new SpriteAtlas(); + + ConfigureAtlasSettings(atlas, config); + AddSpritesToAtlas(atlas, AtlasContents[atlasName]); + + if (!AssetDatabase.Contains(atlas)) + { + AssetDatabase.CreateAsset(atlas, path); + } + else + { + EditorUtility.SetDirty(atlas); + } + } + + private static void ConfigureAtlasSettings(SpriteAtlas atlas, AtlasConfiguration config) + { + // Packing Settings + var packingSettings = new SpriteAtlasPackingSettings + { + padding = config.padding, + enableRotation = config.enableRotation, + blockOffset = config.blockOffset + }; + atlas.SetPackingSettings(packingSettings); + + // Texture Settings + var textureSettings = new SpriteAtlasTextureSettings + { + generateMipMaps = false, + sRGB = true, + filterMode = FilterMode.Bilinear + }; + atlas.SetTextureSettings(textureSettings); + + // Platform Settings + SetPlatformFormat(atlas, "Android", config.androidFormat, config); + SetPlatformFormat(atlas, "iPhone", config.iosFormat, config); + SetPlatformFormat(atlas, "WebGL", config.webglFormat, config); + } + + private static void SetPlatformFormat(SpriteAtlas atlas, string platform, + TextureImporterFormat format, AtlasConfiguration config) + { + var settings = atlas.GetPlatformSettings(platform); + settings.overridden = true; + settings.format = format; + settings.compressionQuality = config.compressionQuality; + atlas.SetPlatformSettings(settings); + } + + private static void AddSpritesToAtlas(SpriteAtlas atlas, IEnumerable spritePaths) + { + var packables = new List(); + foreach (var path in spritePaths) + { + var obj = AssetDatabase.LoadAssetAtPath(path); + if (obj != null) packables.Add(obj); + } + atlas.Add(packables.ToArray()); + } +} diff --git a/Editor/Postprocessor/Atlas/AtlasProcessor.cs.meta b/Editor/Postprocessor/Atlas/AtlasProcessor.cs.meta new file mode 100644 index 0000000..c78628d --- /dev/null +++ b/Editor/Postprocessor/Atlas/AtlasProcessor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6e0aa32db2943f742a839708e928fda4 +timeCreated: 1738748262 \ No newline at end of file diff --git a/Editor/Postprocessor/SpritePostprocessor.cs b/Editor/Postprocessor/SpritePostprocessor.cs new file mode 100644 index 0000000..0b290ee --- /dev/null +++ b/Editor/Postprocessor/SpritePostprocessor.cs @@ -0,0 +1,549 @@ +// using System; +// using System.Collections.Generic; +// using System.IO; +// using UnityEditor; +// using UnityEditor.U2D; +// using UnityEngine; +// using UnityEngine.U2D; +// using Object = UnityEngine.Object; +// +// namespace GameFramework.Editor +// { +// /// +// /// 图集导入管线。 +// /// +// public class SpritePostprocessor : AssetPostprocessor +// { +// static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) +// { +// foreach (var s in importedAssets) +// { +// EditorSpriteSaveInfo.OnImportSprite(s); +// } +// +// foreach (var s in deletedAssets) +// { +// EditorSpriteSaveInfo.OnDeleteSprite(s); +// } +// +// foreach (var s in movedFromAssetPaths) +// { +// EditorSpriteSaveInfo.OnDeleteSprite(s); +// } +// +// foreach (var s in movedAssets) +// { +// EditorSpriteSaveInfo.OnImportSprite(s); +// } +// } +// } +// +// public static class EditorSpriteSaveInfo +// { +// private const string NormalAtlasDir = "Assets/AssetArt/Atlas"; +// private const string UISpritePath = "Assets/AssetRaw/UIRaw"; +// private const string UIAtlasPath = "Assets/AssetRaw/UIRaw/Atlas"; +// private static readonly List _dirtyAtlasList = new List(); +// private static readonly Dictionary> _allASprites = new Dictionary>(); +// +// private static readonly Dictionary _uiAtlasMap = new Dictionary(); +// private static bool _isInit = false; +// private static bool m_dirty = false; +// +// public static void Init() +// { +// if (_isInit) +// { +// return; +// } +// +// EditorApplication.update += CheckDirty; +// +// //读取所有图集信息 +// string[] findAssets = AssetDatabase.FindAssets("t:SpriteAtlas", new[] { NormalAtlasDir }); +// foreach (var findAsset in findAssets) +// { +// var path = AssetDatabase.GUIDToAssetPath(findAsset); +// SpriteAtlas sa = AssetDatabase.LoadAssetAtPath(path, typeof(SpriteAtlas)) as SpriteAtlas; +// if (sa == null) +// { +// Debug.LogError($"加载图集数据{path}失败"); +// continue; +// } +// +// string atlasName = Path.GetFileNameWithoutExtension(path); +// var objects = sa.GetPackables(); +// foreach (var o in objects) +// { +// if (!_allASprites.TryGetValue(atlasName, out var list)) +// { +// list = new List(); +// _allASprites.Add(atlasName, list); +// } +// +// list.Add(AssetDatabase.GetAssetPath(o)); +// } +// } +// +// _isInit = true; +// } +// +// public static void CheckDirty() +// { +// if (m_dirty) +// { +// m_dirty = false; +// +// AssetDatabase.Refresh(); +// float lastProgress = -1; +// for (int i = 0; i < _dirtyAtlasList.Count; i++) +// { +// string atlasName = _dirtyAtlasList[i]; +// Debug.Log("更新图集 : " + atlasName); +// var curProgress = (float)i / _dirtyAtlasList.Count; +// if (curProgress > lastProgress + 0.01f) +// { +// lastProgress = curProgress; +// var progressText = $"当前进度:{i}/{_dirtyAtlasList.Count} {atlasName}"; +// bool cancel = EditorUtility.DisplayCancelableProgressBar("刷新图集" + atlasName, progressText, curProgress); +// if (cancel) +// { +// break; +// } +// } +// +// bool isUI = atlasName.StartsWith("UIRaw"); +// SaveAtlas(atlasName, isUI); +// } +// +// EditorUtility.ClearProgressBar(); +// AssetDatabase.SaveAssets(); +// AssetDatabase.Refresh(); +// _dirtyAtlasList.Clear(); +// } +// } +// +// public static void OnImportSprite(string assetPath) +// { +// if (!assetPath.StartsWith(UISpritePath)) +// { +// return; +// } +// +// TextureImporter ti = AssetImporter.GetAtPath(assetPath) as TextureImporter; +// +// if (ti != null) +// { +// var modify = false; +// +// if (assetPath.StartsWith(UISpritePath)) +// { +// if (ti.textureType != TextureImporterType.Sprite) +// { +// ti.textureType = TextureImporterType.Sprite; +// modify = true; +// } +// +// if (!string.IsNullOrEmpty(ti.spritePackingTag)) +// { +// ti.spritePackingTag = string.Empty; +// modify = true; +// } +// +// var setting = new TextureImporterSettings(); +// ti.ReadTextureSettings(setting); +// if (setting.spriteGenerateFallbackPhysicsShape) +// { +// setting.spriteGenerateFallbackPhysicsShape = false; +// ti.SetTextureSettings(setting); +// modify = true; +// } +// +// if (IsKeepRawImage(assetPath)) +// { +// //调整android格式 +// var andPlatformSettings = ti.GetPlatformTextureSettings("Android"); +// if (!andPlatformSettings.overridden) +// { +// andPlatformSettings.overridden = true; +// modify = true; +// } +// +// if (andPlatformSettings.format != TextureImporterFormat.ASTC_6x6) +// { +// andPlatformSettings.format = TextureImporterFormat.ASTC_6x6; +// andPlatformSettings.compressionQuality = 50; +// ti.SetPlatformTextureSettings(andPlatformSettings); +// modify = true; +// } +// +// //调整ios格式 +// var iosPlatformSettings = ti.GetPlatformTextureSettings("iPhone"); +// if (!iosPlatformSettings.overridden) +// { +// iosPlatformSettings.overridden = true; +// modify = true; +// } +// +// if (iosPlatformSettings.format != TextureImporterFormat.ASTC_5x5) +// { +// iosPlatformSettings.format = TextureImporterFormat.ASTC_5x5; +// iosPlatformSettings.compressionQuality = 50; +// ti.SetPlatformTextureSettings(iosPlatformSettings); +// modify = true; +// } +// +// //调整WebGL格式 +// var webglSettings = ti.GetPlatformTextureSettings("WebGL"); +// if (!webglSettings.overridden) +// { +// webglSettings.overridden = true; +// modify = true; +// } +// +// if (webglSettings.format != TextureImporterFormat.ASTC_6x6) +// { +// webglSettings.format = TextureImporterFormat.ASTC_6x6; +// webglSettings.compressionQuality = 50; +// ti.SetPlatformTextureSettings(webglSettings); +// modify = true; +// } +// } +// } +// +// if (modify) +// { +// ti.SaveAndReimport(); +// } +// +// if (ti.textureType == TextureImporterType.Sprite) +// { +// OnProcessSprite(assetPath); +// } +// } +// } +// +// /// +// /// 是否保持散图(不打图集) +// /// +// /// +// /// +// public static bool IsKeepRawImage(string dirPath) +// { +// return dirPath.Contains("UIRaw/Raw/") || dirPath.Contains("UIRaw_Raw_"); +// } +// +// public static string GetSpritePath(string assetPath) +// { +// string path = assetPath.Substring(0, assetPath.LastIndexOf(".", StringComparison.Ordinal)); +// path = path.Replace("Assets/AssetRaw/", ""); +// return path; +// } +// +// /// +// /// 根据文件路径,返回图集名称 +// /// +// /// +// /// +// public static string GetPackageTag(string fullName) +// { +// fullName = fullName.Replace("\\", "/"); +// int idx = fullName.LastIndexOf("UIRaw", StringComparison.Ordinal); +// if (idx == -1) +// { +// return ""; +// } +// +// if (IsKeepRawImage(fullName)) +// { +// return ""; +// } +// +// var atlasPath = fullName.Substring(idx); +// string str = atlasPath; +// str = str.Substring(0, str.LastIndexOf("/", StringComparison.Ordinal)).Replace("/", "_"); +// +// return str; +// } +// +// public static void OnProcessSprite(string assetPath) +// { +// if (!assetPath.StartsWith("Assets")) +// { +// return; +// } +// +// if (assetPath.StartsWith("Assets/UIRaw_Delete")) +// { +// return; +// } +// +// Init(); +// +// var spriteName = Path.GetFileNameWithoutExtension(assetPath); +// var spritePath = GetSpritePath(assetPath); +// if (!_uiAtlasMap.TryGetValue(spriteName, out string oldAssetPath) || spritePath == oldAssetPath) +// { +// _uiAtlasMap[spriteName] = spritePath; +// m_dirty = true; +// } +// else +// { +// Debug.LogError($"有重名的图片:{spriteName}\n旧图集:{oldAssetPath}\n新图集:{spritePath} "); +// _uiAtlasMap[spriteName] = spritePath; +// m_dirty = true; +// } +// +// string atlasName = GetPackageTag(assetPath); +// if (string.IsNullOrEmpty(atlasName)) +// { +// bool keepRaw = IsKeepRawImage(assetPath); +// if (!keepRaw) +// { +// Debug.LogError($"empty packingTag of asset :{assetPath} !!!"); +// } +// +// return; +// } +// else +// { +// List ret; +// if (!_allASprites.TryGetValue(atlasName, out ret)) +// { +// ret = new List(); +// _allASprites.Add(atlasName, ret); +// } +// +// if (!ret.Contains(assetPath)) +// { +// ret.Add(assetPath); +// m_dirty = true; +// if (!_dirtyAtlasList.Contains(atlasName)) +// { +// _dirtyAtlasList.Add(atlasName); +// } +// } +// } +// } +// +// public static void OnDeleteSprite(string assetPath) +// { +// if (assetPath.StartsWith("Assets/UIRaw_Delete")) +// { +// return; +// } +// +// if (!assetPath.StartsWith(UISpritePath)) +// { +// return; +// } +// +// Init(); +// string atlasName = GetPackageTag(assetPath); +// if (!_allASprites.TryGetValue(atlasName, out var ret)) +// { +// return; +// } +// +// //改成文件名的匹配 +// if (!ret.Exists(s => Path.GetFileName(s) == Path.GetFileName(assetPath))) +// { +// return; +// } +// +// if (assetPath.StartsWith(UISpritePath)) +// { +// var spriteName = Path.GetFileNameWithoutExtension(assetPath); +// if (_uiAtlasMap.ContainsKey(spriteName)) +// { +// _uiAtlasMap.Remove(spriteName); +// m_dirty = true; +// } +// } +// +// ret.Remove(assetPath); +// m_dirty = true; +// if (!_dirtyAtlasList.Contains(atlasName)) +// { +// _dirtyAtlasList.Add(atlasName); +// } +// } +// +// #region 更新图集 +// +// public static void SaveAtlas(string atlasName, bool isUI) +// { +// List spriteList = new List(); +// if (_allASprites.TryGetValue(atlasName, out var list)) +// { +// list.Sort(StringComparer.Ordinal); +// +// foreach (var s in list) +// { +// var sprite = AssetDatabase.LoadAssetAtPath(s); +// if (sprite != null) +// { +// spriteList.Add(sprite); +// } +// } +// } +// +// var path = $"{NormalAtlasDir}/{atlasName}.spriteatlas"; +// +// if (spriteList.Count == 0) +// { +// if (File.Exists(path)) +// { +// AssetDatabase.DeleteAsset(path); +// } +// +// return; +// } +// +// var atlas = new SpriteAtlas(); +// // var atlas = new SpriteAtlasAsset(); +// var setting = new SpriteAtlasPackingSettings +// { +// blockOffset = 1, +// padding = 2, +// enableRotation = true +// }; +// +// bool isOpaque = atlasName.Contains("Opaque"); +// +// var textureSetting = new SpriteAtlasTextureSettings +// { +// generateMipMaps = false, +// sRGB = true, +// filterMode = FilterMode.Bilinear +// }; +// atlas.SetTextureSettings(textureSetting); +// +// var iphonePlatformSetting = atlas.GetPlatformSettings("iPhone"); +// if (!iphonePlatformSetting.overridden) +// { +// iphonePlatformSetting.overridden = true; +// iphonePlatformSetting.format = TextureImporterFormat.ASTC_5x5; +// iphonePlatformSetting.compressionQuality = 100; +// atlas.SetPlatformSettings(iphonePlatformSetting); +// } +// +// var androidPlatformSetting = atlas.GetPlatformSettings("Android"); +// if (!androidPlatformSetting.overridden) +// { +// androidPlatformSetting.overridden = true; +// androidPlatformSetting.format = TextureImporterFormat.ASTC_6x6; +// androidPlatformSetting.compressionQuality = 100; +// atlas.SetPlatformSettings(androidPlatformSetting); +// } +// +// var webglSettings = atlas.GetPlatformSettings("WebGL"); +// if (!webglSettings.overridden) +// { +// webglSettings.overridden = true; +// webglSettings.format = TextureImporterFormat.ASTC_6x6; +// webglSettings.compressionQuality = 50; +// atlas.SetPlatformSettings(webglSettings); +// } +// +// atlas.SetPackingSettings(setting); +// atlas.Add(spriteList.ToArray()); +// +// AssetDatabase.CreateAsset(atlas, path); +// AssetDatabase.SaveAssets(); +// AssetDatabase.Refresh(); +// } +// +// #endregion +// +// #region 重新生成图集 +// +// private static readonly Dictionary> m_tempAllASprites = new Dictionary>(); +// +// [MenuItem("开发工具/Atlas/重新生成UI图集", false, 90)] +// static void ForceGenAtlas() +// { +// Init(); +// List needSaveAtlas = new List(); +// m_tempAllASprites.Clear(); +// _allASprites.Clear(); +// var findAssets = AssetDatabase.FindAssets("t:sprite", new[] { UIAtlasPath }); +// foreach (var findAsset in findAssets) +// { +// var path = AssetDatabase.GUIDToAssetPath(findAsset); +// var atlasName = GetPackageTag(path); +// if (!m_tempAllASprites.TryGetValue(atlasName, out var spriteList)) +// { +// spriteList = new List(); +// m_tempAllASprites[atlasName] = spriteList; +// } +// +// if (!spriteList.Contains(path)) +// { +// spriteList.Add(path); +// } +// } +// +// //有变化的才刷 +// var iter = m_tempAllASprites.GetEnumerator(); +// while (iter.MoveNext()) +// { +// bool needSave = false; +// var atlasName = iter.Current.Key; +// var newSpritesList = iter.Current.Value; +// +// if (_allASprites.TryGetValue(atlasName, out var existSprites)) +// { +// if (existSprites.Count != newSpritesList.Count) +// { +// needSave = true; +// existSprites.Clear(); +// existSprites.AddRange(newSpritesList); +// } +// else +// { +// for (int i = 0; i < newSpritesList.Count; i++) +// { +// if (!existSprites.Contains(newSpritesList[i])) +// { +// needSave = true; +// break; +// } +// } +// +// if (needSave) +// { +// existSprites.Clear(); +// existSprites.AddRange(newSpritesList); +// } +// } +// } +// else +// { +// needSave = true; +// _allASprites.Add(atlasName, new List(newSpritesList)); +// } +// +// if (needSave && !needSaveAtlas.Contains(atlasName)) +// { +// needSaveAtlas.Add(atlasName); +// } +// } +// +// iter.Dispose(); +// foreach (var atlas in needSaveAtlas) +// { +// Debug.LogFormat("Gen atlas:{0}", atlas); +// SaveAtlas(atlas, true); +// } +// +// AssetDatabase.SaveAssets(); +// AssetDatabase.Refresh(); +// +// SpriteAtlasUtility.PackAllAtlases(EditorUserBuildSettings.activeBuildTarget); +// Debug.Log("Gen end"); +// } +// +// #endregion +// } +// } diff --git a/Editor/Postprocessor/SpritePostprocessor.cs.meta b/Editor/Postprocessor/SpritePostprocessor.cs.meta new file mode 100644 index 0000000..c0115d7 --- /dev/null +++ b/Editor/Postprocessor/SpritePostprocessor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7342886aa5c4714bb6064c63e116892 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ToolBar.meta b/Editor/ToolBar.meta new file mode 100644 index 0000000..728d15b --- /dev/null +++ b/Editor/ToolBar.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 93fb9d2834752b649891dba19cba5169 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/ToolBar/BuildSettingWindow.cs b/Editor/ToolBar/BuildSettingWindow.cs new file mode 100644 index 0000000..75a8529 --- /dev/null +++ b/Editor/ToolBar/BuildSettingWindow.cs @@ -0,0 +1,26 @@ +// using Paps.UnityToolbarExtenderUIToolkit; +// using UnityEditor; +// using UnityEngine; +// using UnityEngine.UIElements; +// +// [MainToolbarElement(id: "BuildSettingWindow", alignment: ToolbarAlign.Right, order: 3)] +// public class BuildSettingWindow : IMGUIContainer +// { +// private GUIContent buildBtContent; +// +// public void InitializeElement() +// { +// buildBtContent = EditorGUIUtility.TrTextContentWithIcon("Build App/Hotfix", "打新包/打热更", EditorGUIUtility.IconContent("d_BuildSettings.Standalone").image); +// onGUIHandler = MyGUIMethod; +// } +// +// private void MyGUIMethod() +// { +// GUILayout.BeginHorizontal(); +// +// if (GUILayout.Button(buildBtContent, EditorStyles.toolbarButton, GUILayout.MaxWidth(125))) +// Debug.Log("GUI Button clicked"); +// +// GUILayout.EndHorizontal(); +// } +// } diff --git a/Editor/ToolBar/BuildSettingWindow.cs.meta b/Editor/ToolBar/BuildSettingWindow.cs.meta new file mode 100644 index 0000000..6931208 --- /dev/null +++ b/Editor/ToolBar/BuildSettingWindow.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b7b9f8865a200e04b81804580b6d1de1 +timeCreated: 1741240351 \ No newline at end of file diff --git a/Editor/ToolBar/EditorQuickToolBar.cs b/Editor/ToolBar/EditorQuickToolBar.cs new file mode 100644 index 0000000..d46e0f0 --- /dev/null +++ b/Editor/ToolBar/EditorQuickToolBar.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Paps.UnityToolbarExtenderUIToolkit; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace AlicizaX.Editor.Extension +{ + [MainToolbarElement("EditorQuickToolBar", alignment: ToolbarAlign.Right, order: 1)] + public class EditorQuickToolBar : IMGUIContainer + { + private static GUIContent toolsDropBtContent; + + public void InitializeElement() + { + toolsDropBtContent = EditorGUIUtility.TrTextContentWithIcon("Tools", "工具箱", "CustomTool"); + onGUIHandler = MyGUIMethod; + } + + private void MyGUIMethod() + { + GUILayout.BeginHorizontal(); + if (EditorGUILayout.DropdownButton(toolsDropBtContent, FocusType.Passive, EditorStyles.toolbarPopup, + GUILayout.MaxWidth(90))) + { + DrawEditorToolDropdownMenus(); + } + + GUILayout.Space(5); + GUILayout.EndHorizontal(); + } + + static void DrawEditorToolDropdownMenus() + { + GenericMenu popMenu = new GenericMenu(); + for (int i = 0; i < EditorToolFunctionAttributeCollector.Attributes.Count; i++) + { + var toolAttr = EditorToolFunctionAttributeCollector.Attributes[i]; + popMenu.AddItem(new GUIContent(toolAttr.ToolMenuPath), false, + menuIdx => { ClickToolsSubmenu((int)menuIdx); }, i); + } + + popMenu.ShowAsContext(); + } + + static void ClickToolsSubmenu(int menuIdx) + { + var editorTp = EditorToolFunctionAttributeCollector.Attributes[menuIdx]; + if (editorTp.MethodInfo != null && editorTp.MethodInfo.IsStatic) + { + editorTp.MethodInfo.Invoke(null, null); // Invoke the static method + } + else + { + Debug.LogError("Method is not static or not found."); + } + } + } +} diff --git a/Editor/ToolBar/EditorQuickToolBar.cs.meta b/Editor/ToolBar/EditorQuickToolBar.cs.meta new file mode 100644 index 0000000..a040351 --- /dev/null +++ b/Editor/ToolBar/EditorQuickToolBar.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e90a4f0e05216af4cac67f19d3b4b206 +timeCreated: 1741334878 \ No newline at end of file diff --git a/Editor/ToolBar/ResourceModeDropdownField.cs b/Editor/ToolBar/ResourceModeDropdownField.cs new file mode 100644 index 0000000..3324846 --- /dev/null +++ b/Editor/ToolBar/ResourceModeDropdownField.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using System.Linq; +using AlicizaX.Resource.Runtime; +using Paps.UnityToolbarExtenderUIToolkit; +using UnityEditor; +using UnityEditor.Toolbars; +using UnityEngine; +using UnityEngine.UIElements; + +namespace AlicizaX.Editor.Extension +{ + [MainToolbarElement("ResourceModeDropdownField", alignment: ToolbarAlign.Right, order: 0)] + public class ResourceModeDropdownField : IMGUIContainer + { + private static GUIContent appConfigBtContent; + + private static readonly string[] _resourceModeNames = + { + "Editor", + "Offline", + "Host", + }; + + public void InitializeElement() + { + appConfigBtContent = + EditorGUIUtility.TrTextContentWithIcon("Res:", "配置App运行时所需DataTable/Config/Procedure", + "Settings"); + onGUIHandler = MyGUIMethod; + } + + private void MyGUIMethod() + { + GUILayout.BeginHorizontal(); + string title = "Res:" + _resourceModeNames[EditorPrefs.GetInt(ResourceComponent.PrefsKey, 0)]; + appConfigBtContent.text = title; + if (EditorGUILayout.DropdownButton(appConfigBtContent, FocusType.Passive, EditorStyles.toolbarPopup, GUILayout.MaxWidth(90))) + { + DrawEditorToolDropdownMenus(); + } + + GUILayout.Space(5); + GUILayout.EndHorizontal(); + } + + static void DrawEditorToolDropdownMenus() + { + int index = EditorPrefs.GetInt(ResourceComponent.PrefsKey, 0); + GenericMenu popMenu = new GenericMenu(); + for (int i = 0; i < _resourceModeNames.Length; i++) + { + var selected = index == i; + var toolAttr = _resourceModeNames[i]; + popMenu.AddItem(new GUIContent(toolAttr), selected, menuIdx => { ClickToolsSubmenu((int)menuIdx); }, i); + } + + popMenu.ShowAsContext(); + } + + static void ClickToolsSubmenu(int menuIdx) + { + EditorPrefs.SetInt(ResourceComponent.PrefsKey, menuIdx); + } + } +} diff --git a/Editor/ToolBar/ResourceModeDropdownField.cs.meta b/Editor/ToolBar/ResourceModeDropdownField.cs.meta new file mode 100644 index 0000000..39c24bf --- /dev/null +++ b/Editor/ToolBar/ResourceModeDropdownField.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 523cb8b9486cefd44952225d19112f50 +timeCreated: 1741056284 \ No newline at end of file diff --git a/Editor/ToolBar/SwitchSceneToolBar.cs b/Editor/ToolBar/SwitchSceneToolBar.cs new file mode 100644 index 0000000..f0631ed --- /dev/null +++ b/Editor/ToolBar/SwitchSceneToolBar.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using Paps.UnityToolbarExtenderUIToolkit; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.UIElements; + +[MainToolbarElement(id: "SwitchSceneToolBar", alignment: ToolbarAlign.Left, order: 1)] +public class SwitchSceneToolBar : IMGUIContainer +{ + private GUIContent switchSceneBtContent; + + public void InitializeElement() + { + var curOpenSceneName = EditorSceneManager.GetActiveScene().name; + switchSceneBtContent = EditorGUIUtility.TrTextContentWithIcon( + string.IsNullOrEmpty(curOpenSceneName) ? "Switch Scene" : curOpenSceneName, "切换场景", "UnityLogo"); + onGUIHandler = MyGUIMethod; + EditorSceneManager.sceneOpened += OnSceneOpened; + } + + private void OnSceneOpened(Scene scene, OpenSceneMode mode) + { + switchSceneBtContent.text = scene.name; + } + + private static List sceneAssetList = new List(); + + private void MyGUIMethod() + { + GUILayout.BeginHorizontal(); + + if (EditorGUILayout.DropdownButton(switchSceneBtContent, FocusType.Passive, EditorStyles.toolbarPopup, + GUILayout.MaxWidth(150))) + { + DrawSwithSceneDropdownMenus(); + } + + GUILayout.EndHorizontal(); + } + + static string[] ScenePath = new[] { "Assets/Bundles/Scenes/", "Assets/Scenes/" }; + private static string RootScenePath = "Assets/Bundles/Scenes/"; + private static string BundleScenePath = "Assets/Scenes/"; + + static void DrawSwithSceneDropdownMenus() + { + GenericMenu popMenu = new GenericMenu(); + popMenu.allowDuplicateNames = true; + var sceneGuids = AssetDatabase.FindAssets("t:Scene", ScenePath); + sceneAssetList.Clear(); + for (int i = 0; i < sceneGuids.Length; i++) + { + var scenePath = AssetDatabase.GUIDToAssetPath(sceneGuids[i]); + sceneAssetList.Add(scenePath); + string fileDir = System.IO.Path.GetDirectoryName(scenePath); + bool isInRootDir = AlicizaX.Runtime.Utility.Path.GetRegularPath(BundleScenePath).TrimEnd('/') == + AlicizaX.Runtime.Utility.Path.GetRegularPath(fileDir).TrimEnd('/'); + var sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath); + string displayName = sceneName; + if (!isInRootDir) + { + var sceneDir = System.IO.Path.GetRelativePath(RootScenePath, fileDir); + displayName = $"{sceneDir}/{sceneName}"; + } + + popMenu.AddItem(new GUIContent(displayName), false, menuIdx => { SwitchScene((int)menuIdx); }, i); + } + + popMenu.ShowAsContext(); + } + + private static void SwitchScene(int menuIdx) + { + if (menuIdx >= 0 && menuIdx < sceneAssetList.Count) + { + var scenePath = sceneAssetList[menuIdx]; + var curScene = EditorSceneManager.GetActiveScene(); + if (curScene != null && curScene.isDirty) + { + int opIndex = + EditorUtility.DisplayDialogComplex("警告", $"当前场景{curScene.name}未保存,是否保存?", "保存", "取消", "不保存"); + switch (opIndex) + { + case 0: + if (!EditorSceneManager.SaveOpenScenes()) + { + return; + } + + break; + case 1: + return; + } + } + + EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single); + } + } +} diff --git a/Editor/ToolBar/SwitchSceneToolBar.cs.meta b/Editor/ToolBar/SwitchSceneToolBar.cs.meta new file mode 100644 index 0000000..6e7eaeb --- /dev/null +++ b/Editor/ToolBar/SwitchSceneToolBar.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d69410e234f1b134f9eae9be73bc5e32 +timeCreated: 1741329998 \ No newline at end of file