├── .UnityInternals ├── README.txt ├── UnityEditorInternals.Android │ ├── CustomAndroidBuildOptions.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── UnityEditorInternals.Android.csproj ├── UnityEditorInternals.Ios │ ├── CustomIosBuildOptions.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── UnityEditorInternals.Ios.csproj ├── UnityEditorInternals │ ├── ConsoleWindowProxy.cs │ ├── CustomBuildOptions.cs │ ├── DrawerReplacer.cs │ ├── EditorGUIHelper.cs │ ├── EditorGUILayoutHelper.cs │ ├── EditorGUIUtilityProxy.cs │ ├── IDelayable.cs │ ├── LogEntries.cs │ ├── LogEntry.cs │ ├── MonoImporterProxy.cs │ ├── MonoScriptExtensions.cs │ ├── ProjectWindowUtilProxy.cs │ ├── PropertyDrawerExtensions.cs │ ├── SerializedPropertyExtensions.cs │ └── UnityEditorInternals.csproj ├── UnityEngineInternals │ ├── GUIClip.cs │ ├── ObjectCopy │ │ ├── ArrayExtensions.cs │ │ ├── ArrayTraverse.cs │ │ ├── ObjectExtensions.cs │ │ └── ReferenceEqualityComparer.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── UnityEngineInternals.csproj └── UnityInternals.sln ├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .releaserc.json ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── Editor.meta ├── Editor ├── Extensions.meta ├── Extensions │ ├── EditorWindowExtensions.cs │ ├── EditorWindowExtensions.cs.meta │ ├── MonoScriptExtensions.cs │ ├── MonoScriptExtensions.cs.meta │ ├── RectExtensions.cs │ ├── RectExtensions.cs.meta │ ├── SerializedObjectExtensions.cs │ ├── SerializedObjectExtensions.cs.meta │ ├── SerializedObjectValuesCopier.cs │ ├── SerializedObjectValuesCopier.cs.meta │ ├── SerializedPropertyExtensions.cs │ └── SerializedPropertyExtensions.cs.meta ├── Helpers.meta ├── Helpers │ ├── AssemblyGeneration.cs │ ├── AssemblyGeneration.cs.meta │ ├── AssetDatabaseHelper.cs │ ├── AssetDatabaseHelper.cs.meta │ ├── AssetHelper.cs │ ├── AssetHelper.cs.meta │ ├── ChildProperties.cs │ ├── ChildProperties.cs.meta │ ├── DrawerReplacer.cs │ ├── DrawerReplacer.cs.meta │ ├── EditorDrawHelper.MixedValue.cs │ ├── EditorDrawHelper.MixedValue.cs.meta │ ├── EditorDrawHelper.PropertyWrapper.cs │ ├── EditorDrawHelper.PropertyWrapper.cs.meta │ ├── EditorDrawHelper.SearchToolbarStyle.cs │ ├── EditorDrawHelper.SearchToolbarStyle.cs.meta │ ├── EditorGUIHelper.cs │ ├── EditorGUIHelper.cs.meta │ ├── EditorGUILayoutHelper.cs │ ├── EditorGUILayoutHelper.cs.meta │ ├── EditorGUIUtilityHelper.cs │ ├── EditorGUIUtilityHelper.cs.meta │ ├── EditorHelper.cs │ ├── EditorHelper.cs.meta │ ├── EditorIcons.cs │ ├── EditorIcons.cs.meta │ ├── EditorIconsRelated.meta │ ├── EditorIconsRelated │ │ ├── Active Dark Skin.mat │ │ ├── Active Dark Skin.mat.meta │ │ ├── Active Light Skin.mat │ │ ├── Active Light Skin.mat.meta │ │ ├── Editor Icon Shader.shader │ │ ├── Editor Icon Shader.shader.meta │ │ ├── Editor Icons Database.asset │ │ ├── Editor Icons Database.asset.meta │ │ ├── EditorIcon.cs │ │ ├── EditorIcon.cs.meta │ │ ├── EditorIconsDatabase.cs │ │ ├── EditorIconsDatabase.cs.meta │ │ ├── Highlighted Dark Skin.mat │ │ ├── Highlighted Dark Skin.mat.meta │ │ ├── Highlighted Light Skin.mat │ │ └── Highlighted Light Skin.mat.meta │ ├── GUIContentHelper.cs │ ├── GUIContentHelper.cs.meta │ ├── LogHelper.cs │ ├── LogHelper.cs.meta │ ├── PackageSearcher.cs │ ├── PackageSearcher.cs.meta │ ├── ProjectDependencySearcher.cs │ ├── ProjectDependencySearcher.cs.meta │ ├── ProjectWideSearcher.cs │ ├── ProjectWideSearcher.cs.meta │ ├── SerializedPropertyHelper.cs │ ├── SerializedPropertyHelper.cs.meta │ ├── StackTraceHelper.cs │ ├── StackTraceHelper.cs.meta │ ├── TemporaryActiveTexture.cs │ ├── TemporaryActiveTexture.cs.meta │ ├── TemporaryRenderTexture.cs │ ├── TemporaryRenderTexture.cs.meta │ ├── TextureHelper.cs │ └── TextureHelper.cs.meta ├── PropertyDrawers.meta ├── PropertyDrawers │ ├── ReadOnlyDrawer.cs │ ├── ReadOnlyDrawer.cs.meta │ ├── ResizableTextAreaAttributeDrawer.cs │ ├── ResizableTextAreaAttributeDrawer.cs.meta │ ├── SerializableDictionaryPropertyDrawer.cs │ └── SerializableDictionaryPropertyDrawer.cs.meta ├── SolidUtilities.Editor.asmdef └── SolidUtilities.Editor.asmdef.meta ├── LICENSE ├── LICENSE.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── Attributes.meta ├── Attributes │ ├── ReadOnlyAttribute.cs │ ├── ReadOnlyAttribute.cs.meta │ ├── ResizableTextAreaAttribute.cs │ └── ResizableTextAreaAttribute.cs.meta ├── Extensions.meta ├── Extensions │ ├── CollectionExtensions.cs │ ├── CollectionExtensions.cs.meta │ ├── DictionaryExtensions.cs │ ├── DictionaryExtensions.cs.meta │ ├── EnumExtensions.cs │ ├── EnumExtensions.cs.meta │ ├── EnumerableExtensions.cs │ ├── EnumerableExtensions.cs.meta │ ├── FloatExtensions.cs │ ├── FloatExtensions.cs.meta │ ├── HashSetExtensions.cs │ ├── HashSetExtensions.cs.meta │ ├── MemberInfoExtensions.cs │ ├── MemberInfoExtensions.cs.meta │ ├── RectExtensions.cs │ ├── RectExtensions.cs.meta │ ├── RectLineIntersectionHelper.cs │ ├── RectLineIntersectionHelper.cs.meta │ ├── RegexExtensions.cs │ ├── RegexExtensions.cs.meta │ ├── SpanExtensions.cs │ ├── SpanExtensions.cs.meta │ ├── StringExtensions.cs │ ├── StringExtensions.cs.meta │ ├── Texture2DExtensions.cs │ ├── Texture2DExtensions.cs.meta │ ├── TypeExtensions.cs │ ├── TypeExtensions.cs.meta │ ├── Vector2Extensions.cs │ └── Vector2Extensions.cs.meta ├── Helpers.meta ├── Helpers │ ├── ArrayEqualityComparer.cs │ ├── ArrayEqualityComparer.cs.meta │ ├── ArrayHelper.cs │ ├── ArrayHelper.cs.meta │ ├── FastIterationDictionary.cs │ ├── FastIterationDictionary.cs.meta │ ├── FuzzySearch.cs │ ├── FuzzySearch.cs.meta │ ├── GUIHelper.cs │ ├── GUIHelper.cs.meta │ ├── GUILayoutAreaBlock.cs │ ├── GUILayoutAreaBlock.cs.meta │ ├── GUILayoutHelper.cs │ ├── GUILayoutHelper.cs.meta │ ├── Hash.cs │ ├── Hash.cs.meta │ ├── ListHelper.cs │ ├── ListHelper.cs.meta │ ├── PathHelper.cs │ ├── PathHelper.cs.meta │ ├── Timer.cs │ ├── Timer.cs.meta │ ├── TypeHelper.cs │ └── TypeHelper.cs.meta ├── SerializableCollections.meta ├── SerializableCollections │ ├── LICENSE │ ├── LICENSE.meta │ ├── SerializableDictionary.cs │ └── SerializableDictionary.cs.meta ├── SolidUtilities.asmdef └── SolidUtilities.asmdef.meta ├── UnityEditorInternals.Android.dll ├── UnityEditorInternals.Android.dll.meta ├── UnityEditorInternals.Ios.dll ├── UnityEditorInternals.Ios.dll.meta ├── UnityEditorInternals.dll ├── UnityEditorInternals.dll.meta ├── UnityEditorInternals2019.dll ├── UnityEditorInternals2019.dll.meta ├── UnityEngineInternals.dll ├── UnityEngineInternals.dll.meta ├── package.json └── package.json.meta /.UnityInternals/README.txt: -------------------------------------------------------------------------------- 1 | Projects in this solution contain calls to Unity internal methods. They are highlighted as errors but upon building the project, those errors will be ignored. 2 | After building a project, the DLL file will be copied over to the parent folder of UnityInternals~, so you will be able to use the updated DLL in Unity after building it. 3 | Projects a built with help of OpenSesame. Check it out at this link https://github.com/mob-sakai/OpenSesame 4 | 5 | During development, you can choose which version of the DLL to build: for 2019, or for 2020 or newer. It depends on the Unity version you are developing the plugin in. 6 | However, when publishing the plugin, please build the solution for both Unity2019 and Unity2020 so that it works in all versions. -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals.Android/CustomAndroidBuildOptions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using System.Collections.Generic; 4 | using UnityEditor.Android; 5 | 6 | public static class CustomAndroidBuildOptions 7 | { 8 | private static CustomAndroidWindowExtension _customAndroidExtension; 9 | 10 | public static void AddOptionsDrawer(ICustomBuildOptionsDrawer customDrawer) 11 | { 12 | if (_customAndroidExtension == null) 13 | { 14 | _customAndroidExtension = new CustomAndroidWindowExtension(); 15 | UnityEditor.Android.TargetExtension.s_BuildWindow = _customAndroidExtension; 16 | } 17 | 18 | _customAndroidExtension.CustomDrawers.Add(customDrawer); 19 | } 20 | } 21 | 22 | internal class CustomAndroidWindowExtension : AndroidBuildWindowExtension 23 | { 24 | public readonly List CustomDrawers = new List(); 25 | 26 | public override void ShowPlatformBuildOptions() 27 | { 28 | base.ShowPlatformBuildOptions(); 29 | 30 | foreach (ICustomBuildOptionsDrawer customDrawer in CustomDrawers) 31 | { 32 | customDrawer.DrawBuildOptions(); 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals.Android/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("UnityEditorInternals.Android")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("UnityEditorInternals.Android")] 12 | [assembly: AssemblyCopyright("Copyright © 2021")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("5DC6C857-1750-4A13-A501-0F57F943C5B5")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals.Android/UnityEditorInternals.Android.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5DC6C857-1750-4A13-A501-0F57F943C5B5} 8 | Library 9 | Properties 10 | UnityEditorInternals.Android 11 | UnityEditorInternals.Android 12 | v4.8 13 | 512 14 | <_OutputCopyLocation>..\..\ 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | Unity.InternalAPIEditorBridgeDev.002 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | UnityEditorInternals.Android 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | C:\Program Files\Unity Editors\2020.3.13f1\Editor\Data\Managed\UnityEditor.dll 44 | 45 | 46 | C:\Program Files\Unity Editors\2020.3.16f1\Editor\Data\PlaybackEngines\AndroidPlayer\UnityEditor.Android.Extensions.dll 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {6afdaa30-6e6a-425a-a1a5-684150a80ebb} 56 | UnityEditorInternals 57 | 58 | 59 | 60 | 61 | all 62 | runtime; build; native; contentfiles; analyzers; buildtransitive 63 | 64 | 65 | 66 | 73 | 74 | <_FilesToCopy Include="$(OutputPath)$(AssemblyName).*" /> 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals.Ios/CustomIosBuildOptions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using System.Collections.Generic; 4 | using UnityEditor.Modules; 5 | using UnityEditor.iOS; 6 | 7 | public static class CustomIosBuildOptions 8 | { 9 | private const string Ios = "iOS"; 10 | 11 | private static CustomIosWindowExtension _customIosExtension; 12 | 13 | public static void AddIosOptionsDrawer(ICustomBuildOptionsDrawer customDrawer) 14 | { 15 | if (!ModuleManager.platformSupportModules.ContainsKey(Ios)) 16 | { 17 | return; 18 | } 19 | 20 | if (_customIosExtension == null) 21 | { 22 | _customIosExtension = new CustomIosWindowExtension(); 23 | ((UnityEditor.iOS.TargetExtension) ModuleManager.platformSupportModules[Ios]).buildWindow = _customIosExtension; 24 | } 25 | 26 | _customIosExtension.CustomDrawers.Add(customDrawer); 27 | } 28 | } 29 | 30 | internal class CustomIosWindowExtension : iOSBuildWindowExtension 31 | { 32 | public readonly List CustomDrawers = new List(); 33 | 34 | public override void ShowPlatformBuildOptions() 35 | { 36 | base.ShowPlatformBuildOptions(); 37 | 38 | foreach (ICustomBuildOptionsDrawer customDrawer in CustomDrawers) 39 | { 40 | customDrawer.DrawBuildOptions(); 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals.Ios/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("UnityEditorInternals.Ios")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("UnityEditorInternals.Ios")] 12 | [assembly: AssemblyCopyright("Copyright © 2021")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("38E8226C-70A9-4998-9E20-CA031DB9EA2C")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals.Ios/UnityEditorInternals.Ios.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {38E8226C-70A9-4998-9E20-CA031DB9EA2C} 8 | Library 9 | Properties 10 | UnityEditorInternals.Ios 11 | UnityEditorInternals.Ios 12 | v4.8 13 | 512 14 | <_OutputCopyLocation>..\..\ 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | Unity.InternalAPIEditorBridgeDev.003 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | UnityEditorInternals.Ios 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | C:\Program Files\Unity Editors\2020.3.13f1\Editor\Data\Managed\UnityEditor.dll 44 | 45 | 46 | C:\Program Files\Unity Editors\2020.3.13f1\Editor\Data\PlaybackEngines\iOSSupport\UnityEditor.iOS.Extensions.dll 47 | 48 | 49 | C:\Program Files\Unity Editors\2020.3.13f1\Editor\Data\PlaybackEngines\iOSSupport\UnityEditor.iOS.Extensions.Common.dll 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {6afdaa30-6e6a-425a-a1a5-684150a80ebb} 59 | UnityEditorInternals 60 | 61 | 62 | 63 | 64 | all 65 | runtime; build; native; contentfiles; analyzers; buildtransitive 66 | 67 | 68 | 69 | 76 | 77 | <_FilesToCopy Include="$(OutputPath)$(AssemblyName).*" /> 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/ConsoleWindowProxy.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using UnityEditor; 4 | 5 | public static class ConsoleWindowProxy 6 | { 7 | public static string StacktraceWithHyperlinks(string stackTrace, int startFrom) 8 | { 9 | return ConsoleWindow.StacktraceWithHyperlinks(stackTrace, startFrom); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/CustomBuildOptions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | public interface ICustomBuildOptionsDrawer 4 | { 5 | void DrawBuildOptions(); 6 | } 7 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/DrawerReplacer.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using JetBrains.Annotations; 4 | using UnityEditor; 5 | 6 | public static class DrawerReplacer 7 | { 8 | [PublicAPI] 9 | public static void ReplaceDefaultDrawer() 10 | where TDrawer : PropertyDrawer 11 | { 12 | if (ScriptAttributeUtility.s_DrawerTypeForType == null) 13 | { 14 | ScriptAttributeUtility.BuildDrawerTypeForTypeDictionary(); 15 | } 16 | 17 | var keySet = new ScriptAttributeUtility.DrawerKeySet 18 | { 19 | type = typeof(TObject), 20 | drawer = typeof(TDrawer) 21 | }; 22 | 23 | ScriptAttributeUtility.s_DrawerTypeForType[typeof(TObject)] = keySet; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/EditorGUIUtilityProxy.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using System.Reflection; 4 | using JetBrains.Annotations; 5 | using UnityEditor; 6 | using UnityEngine; 7 | using Object = UnityEngine.Object; 8 | 9 | public static class EditorGUIUtilityProxy 10 | { 11 | private static FieldInfo _showModeField; 12 | 13 | private static FieldInfo ShowModeField 14 | { 15 | get 16 | { 17 | if (_showModeField == null) 18 | { 19 | _showModeField = typeof(ContainerWindow).GetField( 20 | "m_ShowMode", 21 | BindingFlags.NonPublic | BindingFlags.Instance); 22 | } 23 | 24 | return _showModeField; 25 | } 26 | } 27 | 28 | [PublicAPI] 29 | public static void SetIconForObject(Object obj, Texture2D icon) 30 | { 31 | EditorGUIUtility.SetIconForObject(obj, icon); 32 | } 33 | 34 | /// 35 | /// Returns position of Unity Editor's main window. In Unity 2020.1 or newer, 36 | /// use . 37 | /// 38 | /// Position of Unity Editor's main window. 39 | [PublicAPI] 40 | public static Rect GetMainWindowPosition() 41 | { 42 | const int mainWindowIndex = 4; 43 | 44 | var windows = Resources.FindObjectsOfTypeAll(); 45 | 46 | foreach (ContainerWindow win in windows) 47 | { 48 | if ((int) ShowModeField.GetValue(win) != mainWindowIndex || win.m_DontSaveToLayout) 49 | continue; 50 | 51 | return win.position; 52 | } 53 | 54 | return new Rect(0.0f, 0.0f, 1000f, 600f); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/IDelayable.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | public interface IDelayable 7 | { 8 | void OnGUIDelayed(Rect rect, SerializedProperty property, GUIContent label); 9 | } 10 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/LogEntries.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | public static class LogEntries 4 | { 5 | public static int GetCount() => UnityEditor.LogEntries.GetCount(); 6 | 7 | public static (int errorCount, int warningCount, int logCount) GetCountsByType() 8 | { 9 | int errorCount, warningCount, logCount; 10 | errorCount = warningCount = logCount = 0; 11 | 12 | UnityEditor.LogEntries.GetCountsByType(ref errorCount, ref warningCount, ref logCount); 13 | 14 | return (errorCount, warningCount, logCount); 15 | } 16 | 17 | public static void Clear() => UnityEditor.LogEntries.Clear(); 18 | } 19 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/LogEntry.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | public static class LogEntry 4 | { 5 | public static void Internal_RemoveLogEntriesByMode(int mode) => UnityEditor.LogEntry.RemoveLogEntriesByMode(mode); 6 | } 7 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/MonoImporterProxy.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using UnityEditor; 4 | 5 | public static class MonoImporterProxy 6 | { 7 | public static void CopyMonoScriptIconToImporters(MonoScript script) => MonoImporter.CopyMonoScriptIconToImporters(script); 8 | } 9 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/MonoScriptExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using UnityEditor; 4 | 5 | public static class MonoScriptExtensions 6 | { 7 | public static string Internal_GetAssemblyName(this MonoScript script) => script.GetAssemblyName(); 8 | } 9 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/ProjectWindowUtilProxy.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using UnityEditor; 4 | 5 | public static class ProjectWindowUtilProxy 6 | { 7 | public static string GetActiveFolderPath() => ProjectWindowUtil.GetActiveFolderPath(); 8 | } 9 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/PropertyDrawerExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using System.Reflection; 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | public static class PropertyDrawerExtensions 8 | { 9 | public static PropertyAttribute GetAttribute(this PropertyDrawer propertyDrawer) => propertyDrawer.m_Attribute; 10 | 11 | public static void SetAttribute(this PropertyDrawer propertyDrawer, PropertyAttribute value) => propertyDrawer.m_Attribute = value; 12 | 13 | public static FieldInfo GetFieldInfo(this PropertyDrawer propertyDrawer) => propertyDrawer.m_FieldInfo; 14 | 15 | public static void SetFieldInfo(this PropertyDrawer propertyDrawer, FieldInfo fieldInfo) => propertyDrawer.m_FieldInfo = fieldInfo; 16 | } 17 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEditorInternals/SerializedPropertyExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEditorInternals 2 | { 3 | using System; 4 | using System.Reflection; 5 | using JetBrains.Annotations; 6 | using UnityEditor; 7 | 8 | public static class SerializedPropertyExtensions 9 | { 10 | /// Checks if property has custom drawer. 11 | /// The property to check. 12 | /// true if the has a custom drawer. 13 | [PublicAPI] 14 | public static bool HasCustomPropertyDrawer(this SerializedProperty property) 15 | { 16 | return ScriptAttributeUtility.GetHandler(property).propertyDrawer != null; 17 | } 18 | 19 | [PublicAPI] 20 | public static (FieldInfo FieldInfo, Type Type) GetFieldInfoAndType(this SerializedProperty property) 21 | { 22 | var fieldInfo = ScriptAttributeUtility.GetFieldInfoFromProperty(property, out Type type); 23 | return (fieldInfo, type); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEngineInternals/GUIClip.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEngineInternals 2 | { 3 | using UnityEngine; 4 | 5 | public static class GUIClip 6 | { 7 | public static Rect GetVisibleRect() => UnityEngine.GUIClip.visibleRect; 8 | } 9 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEngineInternals/ObjectCopy/ArrayExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEngineInternals 2 | { 3 | using System; 4 | 5 | /// 6 | /// Array data-structure extensions 7 | /// 8 | internal static class ArrayExtensions 9 | { 10 | /// 11 | /// Iterate through all array elements executing a given action for each array item 12 | /// 13 | /// The array. 14 | /// The action. 15 | public static void ForEach(this Array array, Action action) 16 | { 17 | if (array.LongLength == 0) return; 18 | var walker = new ArrayTraverse(array); 19 | do action(array, walker.Position); while (walker.Step()); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEngineInternals/ObjectCopy/ArrayTraverse.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEngineInternals 2 | { 3 | using System; 4 | 5 | // Assist in foreach array traversal 6 | internal readonly struct ArrayTraverse 7 | { 8 | public readonly int[] Position; 9 | private readonly int[] _maxLengths; 10 | 11 | public ArrayTraverse(Array array) 12 | { 13 | _maxLengths = new int[array.Rank]; 14 | 15 | for (int i = 0; i < array.Rank; ++i) 16 | { 17 | _maxLengths[i] = array.GetLength(i) - 1; 18 | } 19 | 20 | Position = new int[array.Rank]; 21 | } 22 | 23 | public bool Step() 24 | { 25 | for (int i = 0; i < Position.Length; ++i) 26 | { 27 | if (Position[i] >= _maxLengths[i]) 28 | continue; 29 | 30 | Position[i]++; 31 | for (int j = 0; j < i; j++) 32 | { 33 | Position[j] = 0; 34 | } 35 | 36 | return true; 37 | } 38 | 39 | return false; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEngineInternals/ObjectCopy/ReferenceEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.UnityEngineInternals 2 | { 3 | using System.Collections.Generic; 4 | using System.Runtime.CompilerServices; 5 | 6 | internal class ReferenceEqualityComparer : EqualityComparer 7 | { 8 | public override bool Equals(object x, object y) 9 | { 10 | return ReferenceEquals(x, y); 11 | } 12 | 13 | public override int GetHashCode(object obj) 14 | { 15 | // The RuntimeHelpers.GetHashCode method always calls the Object.GetHashCode method non-virtually, 16 | // even if the object's type has overridden the Object.GetHashCode method. 17 | return RuntimeHelpers.GetHashCode(obj); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /.UnityInternals/UnityEngineInternals/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("UnityEngineInternals")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("UnityEngineInternals")] 12 | [assembly: AssemblyCopyright("Copyright © 2021")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /.UnityInternals/UnityEngineInternals/UnityEngineInternals.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyUnityVersion 7 | {0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C} 8 | Library 9 | Properties 10 | SolidUtilities.UnityEngineInternals 11 | v4.8 12 | 512 13 | <_OutputCopyLocation>..\..\ 14 | 15 | 16 | pdbonly 17 | true 18 | TRACE 19 | prompt 20 | 4 21 | UnityEngineInternals 22 | bin\Release\ 23 | AnyCPU 24 | 25 | 26 | true 27 | full 28 | false 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | Unity.InternalAPIEditorBridgeDev.002 33 | bin\Debug\ 34 | AnyCPU 35 | 36 | 37 | 38 | 39 | 40 | 41 | C:\Program Files\Unity Editors\2020.3.16f1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll 42 | 43 | 44 | C:\Program Files\Unity Editors\2020.3.16f1\Editor\Data\Managed\UnityEngine\UnityEngine.IMGUIModule.dll 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | all 58 | runtime; build; native; contentfiles; analyzers; buildtransitive 59 | 60 | 61 | 62 | 69 | 70 | <_FilesToCopy Include="$(OutputPath)$(AssemblyName).*" /> 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /.UnityInternals/UnityInternals.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityEditorInternals", "UnityEditorInternals\UnityEditorInternals.csproj", "{94677F00-FD8E-4E12-BC4F-91BF3371C309}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityEngineInternals", "UnityEngineInternals\UnityEngineInternals.csproj", "{0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityEditorInternals.Android", "UnityEditorInternals.Android\UnityEditorInternals.Android.csproj", "{5DC6C857-1750-4A13-A501-0F57F943C5B5}" 8 | EndProject 9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityEditorInternals.Ios", "UnityEditorInternals.Ios\UnityEditorInternals.Ios.csproj", "{38E8226C-70A9-4998-9E20-CA031DB9EA2C}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Release|Unity2020 = Release|Unity2020 14 | Release|Unity2019 = Release|Unity2019 15 | Debug|Unity2020 = Debug|Unity2020 16 | Debug|Unity2019 = Debug|Unity2019 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {94677F00-FD8E-4E12-BC4F-91BF3371C309}.Release|Unity2020.ActiveCfg = Release|Unity2020 20 | {94677F00-FD8E-4E12-BC4F-91BF3371C309}.Release|Unity2020.Build.0 = Release|Unity2020 21 | {94677F00-FD8E-4E12-BC4F-91BF3371C309}.Debug|Unity2020.ActiveCfg = Debug|Unity2020 22 | {94677F00-FD8E-4E12-BC4F-91BF3371C309}.Debug|Unity2020.Build.0 = Debug|Unity2020 23 | {94677F00-FD8E-4E12-BC4F-91BF3371C309}.Debug|Unity2019.ActiveCfg = Debug|Unity2019 24 | {94677F00-FD8E-4E12-BC4F-91BF3371C309}.Debug|Unity2019.Build.0 = Debug|Unity2019 25 | {94677F00-FD8E-4E12-BC4F-91BF3371C309}.Release|Unity2019.ActiveCfg = Release|Unity2019 26 | {94677F00-FD8E-4E12-BC4F-91BF3371C309}.Release|Unity2019.Build.0 = Release|Unity2019 27 | {0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C}.Debug|Unity2019.ActiveCfg = Debug|AnyUnityVersion 28 | {0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C}.Debug|Unity2019.Build.0 = Debug|AnyUnityVersion 29 | {0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C}.Debug|Unity2020.ActiveCfg = Debug|AnyUnityVersion 30 | {0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C}.Debug|Unity2020.Build.0 = Debug|AnyUnityVersion 31 | {0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C}.Release|Unity2019.ActiveCfg = Release|AnyUnityVersion 32 | {0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C}.Release|Unity2019.Build.0 = Release|AnyUnityVersion 33 | {0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C}.Release|Unity2020.ActiveCfg = Release|AnyUnityVersion 34 | {0ECCC8A8-BCF8-4429-A35C-05C9FFD4741C}.Release|Unity2020.Build.0 = Release|AnyUnityVersion 35 | {5DC6C857-1750-4A13-A501-0F57F943C5B5}.Release|Unity2020.ActiveCfg = Release|Any CPU 36 | {5DC6C857-1750-4A13-A501-0F57F943C5B5}.Release|Unity2020.Build.0 = Release|Any CPU 37 | {5DC6C857-1750-4A13-A501-0F57F943C5B5}.Release|Unity2019.ActiveCfg = Release|Any CPU 38 | {5DC6C857-1750-4A13-A501-0F57F943C5B5}.Release|Unity2019.Build.0 = Release|Any CPU 39 | {5DC6C857-1750-4A13-A501-0F57F943C5B5}.Debug|Unity2020.ActiveCfg = Debug|Any CPU 40 | {5DC6C857-1750-4A13-A501-0F57F943C5B5}.Debug|Unity2020.Build.0 = Debug|Any CPU 41 | {5DC6C857-1750-4A13-A501-0F57F943C5B5}.Debug|Unity2019.ActiveCfg = Debug|Any CPU 42 | {5DC6C857-1750-4A13-A501-0F57F943C5B5}.Debug|Unity2019.Build.0 = Debug|Any CPU 43 | {38E8226C-70A9-4998-9E20-CA031DB9EA2C}.Release|Unity2020.ActiveCfg = Release|Any CPU 44 | {38E8226C-70A9-4998-9E20-CA031DB9EA2C}.Release|Unity2020.Build.0 = Release|Any CPU 45 | {38E8226C-70A9-4998-9E20-CA031DB9EA2C}.Release|Unity2019.ActiveCfg = Release|Any CPU 46 | {38E8226C-70A9-4998-9E20-CA031DB9EA2C}.Release|Unity2019.Build.0 = Release|Any CPU 47 | {38E8226C-70A9-4998-9E20-CA031DB9EA2C}.Debug|Unity2020.ActiveCfg = Debug|Any CPU 48 | {38E8226C-70A9-4998-9E20-CA031DB9EA2C}.Debug|Unity2020.Build.0 = Debug|Any CPU 49 | {38E8226C-70A9-4998-9E20-CA031DB9EA2C}.Debug|Unity2019.ActiveCfg = Debug|Any CPU 50 | {38E8226C-70A9-4998-9E20-CA031DB9EA2C}.Debug|Unity2019.Build.0 = Debug|Any CPU 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # 3D models 2 | *.3dm filter=lfs diff=lfs merge=lfs -text 3 | *.3ds filter=lfs diff=lfs merge=lfs -text 4 | *.blend filter=lfs diff=lfs merge=lfs -text 5 | *.c4d filter=lfs diff=lfs merge=lfs -text 6 | *.collada filter=lfs diff=lfs merge=lfs -text 7 | *.dae filter=lfs diff=lfs merge=lfs -text 8 | *.dxf filter=lfs diff=lfs merge=lfs -text 9 | *.fbx filter=lfs diff=lfs merge=lfs -text 10 | *.jas filter=lfs diff=lfs merge=lfs -text 11 | *.lws filter=lfs diff=lfs merge=lfs -text 12 | *.lxo filter=lfs diff=lfs merge=lfs -text 13 | *.ma filter=lfs diff=lfs merge=lfs -text 14 | *.max filter=lfs diff=lfs merge=lfs -text 15 | *.mb filter=lfs diff=lfs merge=lfs -text 16 | *.obj filter=lfs diff=lfs merge=lfs -text 17 | *.ply filter=lfs diff=lfs merge=lfs -text 18 | *.skp filter=lfs diff=lfs merge=lfs -text 19 | *.stl filter=lfs diff=lfs merge=lfs -text 20 | *.ztl filter=lfs diff=lfs merge=lfs -text 21 | # Audio 22 | *.aif filter=lfs diff=lfs merge=lfs -text 23 | *.aiff filter=lfs diff=lfs merge=lfs -text 24 | *.it filter=lfs diff=lfs merge=lfs -text 25 | *.mod filter=lfs diff=lfs merge=lfs -text 26 | *.mp3 filter=lfs diff=lfs merge=lfs -text 27 | *.ogg filter=lfs diff=lfs merge=lfs -text 28 | *.s3m filter=lfs diff=lfs merge=lfs -text 29 | *.wav filter=lfs diff=lfs merge=lfs -text 30 | *.xm filter=lfs diff=lfs merge=lfs -text 31 | # Fonts 32 | *.otf filter=lfs diff=lfs merge=lfs -text 33 | *.ttf filter=lfs diff=lfs merge=lfs -text 34 | # Images 35 | *.bmp filter=lfs diff=lfs merge=lfs -text 36 | *.exr filter=lfs diff=lfs merge=lfs -text 37 | *.gif filter=lfs diff=lfs merge=lfs -text 38 | *.hdr filter=lfs diff=lfs merge=lfs -text 39 | *.iff filter=lfs diff=lfs merge=lfs -text 40 | *.jpeg filter=lfs diff=lfs merge=lfs -text 41 | *.jpg filter=lfs diff=lfs merge=lfs -text 42 | *.pict filter=lfs diff=lfs merge=lfs -text 43 | *.png filter=lfs diff=lfs merge=lfs -text 44 | *.psd filter=lfs diff=lfs merge=lfs -text 45 | *.tga filter=lfs diff=lfs merge=lfs -text 46 | *.tif filter=lfs diff=lfs merge=lfs -text 47 | *.tiff filter=lfs diff=lfs merge=lfs -text 48 | 49 | # Collapse Unity-generated files on GitHub 50 | *.asset linguist-generated 51 | *.mat linguist-generated 52 | *.meta linguist-generated 53 | *.prefab linguist-generated 54 | *.unity linguist-generated -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | release: 8 | name: release 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | with: 13 | fetch-depth: 0 14 | - name: Release 15 | uses: cycjimmy/semantic-release-action@v2 16 | with: 17 | extra_plugins: | 18 | @semantic-release/changelog 19 | @semantic-release/git 20 | branch: master 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Derived From: 2 | # http://kleber-swf.com/the-definitive-gitignore-for-unity-projects/ 3 | 4 | # ======= # 5 | # Private # 6 | # ======= # 7 | _private/ 8 | Release/ 9 | /Help/ 10 | *.shfbproj_* 11 | 12 | /Assets/Zenject/Extras 13 | 14 | # =============== # 15 | # Unity generated # 16 | # =============== # 17 | Temp/ 18 | Obj/ 19 | UnityGenerated/ 20 | Library/ 21 | 22 | # ============ # 23 | # OS generated # 24 | # ============ # 25 | .DS_Store 26 | .DS_Store? 27 | ._* 28 | .Spotlight-V100 29 | .Trashes 30 | Icon? 31 | ehthumbs.db 32 | Thumbs.db 33 | 34 | # Common IntelliJ Platform excludes 35 | 36 | # Jetbrain Rider Cache 37 | **/.idea/* 38 | 39 | *.suo 40 | *.user 41 | .vs/ 42 | [Bb]in/ 43 | [Oo]bj/ 44 | _UpgradeReport_Files/ 45 | [Pp]ackages/ 46 | 47 | Thumbs.db 48 | Desktop.ini 49 | .DS_Store 50 | 51 | # The file being generated in root directory instead of obj/debug https://github.com/dotnet/roslyn/issues/48430 52 | *.GeneratedMSBuildEditorConfig.editorconfig 53 | 54 | *.csproj.DotSettings -------------------------------------------------------------------------------- /.releaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tagFormat": "${version}", 3 | "plugins": [ 4 | ["@semantic-release/commit-analyzer", { "preset": "angular" }], 5 | "@semantic-release/release-notes-generator", 6 | ["@semantic-release/changelog", { "preset": "angular" }], 7 | ["@semantic-release/npm", { "npmPublish": false }], 8 | ["@semantic-release/git", { 9 | "assets": ["package.json", "CHANGELOG.md"], 10 | "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" 11 | }], 12 | "@semantic-release/github" 13 | ] 14 | } -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a92a2f7a3de57d46a9ba6c43b842979 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 57061a4aed1b9914a95360028ec2e581 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Extensions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4cddcd64a3a8482d850451747df2024e 3 | timeCreated: 1601136478 -------------------------------------------------------------------------------- /Editor/Extensions/EditorWindowExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using Editor; 5 | using JetBrains.Annotations; 6 | using UnityEditor; 7 | using UnityEngine; 8 | 9 | /// Different useful extensions for . 10 | public static class EditorWindowExtensions 11 | { 12 | /// Resizes the window to the needed size. 13 | /// The window to change the size of. 14 | /// The width to set. If the value is -1f, the width will not be changed. 15 | /// The height to set. If the value is -1f, the height will not be changed. 16 | /// 17 | /// Thrown if width or height are negative numbers and not -1f. 18 | /// 19 | /// 20 | /// public class DummyWindow : EditorWindow 21 | /// { 22 | /// private void OnCreate(Rect buttonRect) 23 | /// { 24 | /// var windowSize = new Vector2(100f, 100f); 25 | /// ShowAsDropDown(buttonRect, windowSize); 26 | /// } 27 | /// 28 | /// private void OnGUI() 29 | /// { 30 | /// float optimalWidth = CalculateOptimalWidth(); 31 | /// float optimalHeight = Math.Min(_contentHeight, DropdownStyle.MaxWindowHeight); 32 | /// this.Resize(optimalWidth, optimalHeight); 33 | /// } 34 | /// } 35 | /// 36 | [PublicAPI] public static void Resize(this EditorWindow window, float width = -1f, float height = -1f) 37 | { 38 | EnsureTheValueIsNotNegative(nameof(width), width); 39 | EnsureTheValueIsNotNegative(nameof(height), height); 40 | 41 | bool changeWidth = width != -1f; 42 | bool changeHeight = height != -1f; 43 | 44 | Rect positionToAdjust = window.position; 45 | 46 | if (changeWidth) 47 | positionToAdjust.width = width; 48 | 49 | if (changeHeight) 50 | positionToAdjust.height = height; 51 | 52 | window.minSize = new Vector2(changeWidth ? width : window.minSize.x, changeHeight ? height : window.minSize.y); 53 | window.maxSize = new Vector2(changeWidth ? width : window.maxSize.x, changeHeight ? height : window.maxSize.y); 54 | 55 | if (changeWidth) 56 | { 57 | float screenWidth = EditorGUIUtilityHelper.GetScreenWidth(); 58 | if (positionToAdjust.xMax >= screenWidth) 59 | positionToAdjust.x -= positionToAdjust.xMax - screenWidth; 60 | } 61 | 62 | if (changeHeight) 63 | { 64 | // MainWindow is more reliable than Screen.currentResolution.height, especially for the multi-display setup. 65 | float mainWinYMax = EditorGUIUtilityHelper.GetMainWindowPosition().yMax; 66 | 67 | if (positionToAdjust.yMax >= mainWinYMax) 68 | positionToAdjust.y -= positionToAdjust.yMax - mainWinYMax; 69 | } 70 | 71 | window.position = positionToAdjust; 72 | } 73 | 74 | /// Moves the window out of screen to hide but not close it. 75 | /// The window to hide. 76 | [PublicAPI] public static void MoveOutOfScreen(this EditorWindow window) 77 | { 78 | window.position = new Rect( 79 | Screen.currentResolution.width + 10f, 80 | Screen.currentResolution.height + 10f, 81 | 0f, 0f); 82 | } 83 | 84 | /// 85 | /// Centers the window in the main Unity window. This is not the same as centering a window on screen, 86 | /// because the Unity window may not be maximized. 87 | /// 88 | /// The window to center. 89 | [PublicAPI] public static void CenterOnMainWin(this EditorWindow window) 90 | { 91 | Rect main = EditorGUIUtilityHelper.GetMainWindowPosition(); 92 | 93 | Rect pos = window.position; 94 | float centerWidth = (main.width - pos.width) * 0.5f; 95 | float centerHeight = (main.height - pos.height) * 0.5f; 96 | pos.x = main.x + centerWidth; 97 | pos.y = main.y + centerHeight; 98 | window.position = pos; 99 | } 100 | 101 | private static void EnsureTheValueIsNotNegative(string valueName, float value) 102 | { 103 | if (value < 0f && value != -1f) 104 | throw new ArgumentOutOfRangeException(valueName, value, "The value can only be positive or -1f."); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /Editor/Extensions/EditorWindowExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 11e21702843849fe850dfc6674f5d4c1 3 | timeCreated: 1601758336 -------------------------------------------------------------------------------- /Editor/Extensions/MonoScriptExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Reflection; 6 | using System.Text.RegularExpressions; 7 | using JetBrains.Annotations; 8 | using SolidUtilities; 9 | using UnityEditor; 10 | using UnityEditorInternals; 11 | 12 | public static class MonoScriptExtensions 13 | { 14 | private static readonly Regex _namespaceNameRegex = new Regex(@"(?<=namespace[\s]+)[\w_.-]+", RegexOptions.Compiled); 15 | private static readonly Regex _classRegex = new Regex(@"(?<=(class )|(struct )).*?(?=(\s|\n)*(:|{))", RegexOptions.Compiled); 16 | 17 | /// 18 | /// Returns the of the class implemented by this script. Works for types not derived from 19 | /// and generic classes (the file must be named by the "GenericClass`1.cs" template). 20 | /// 21 | /// The script to get the type from. 22 | /// A specific class name to search for. 23 | /// The of the class implemented by this script or , 24 | /// if the type was not found. 25 | [PublicAPI, CanBeNull] public static Type GetClassType(this MonoScript script, string className = null) 26 | { 27 | Type simpleType = script.GetClass(); 28 | if (simpleType != null) 29 | return simpleType; 30 | 31 | string foundClassName = string.IsNullOrEmpty(className) ? GetFirstClassFromText(script.text) : GetFirstClassWithName(script.text, className); 32 | 33 | if (string.IsNullOrEmpty(foundClassName)) 34 | return null; 35 | 36 | string assemblyName = script.GetAssemblyName(); 37 | Assembly assembly; 38 | 39 | try 40 | { 41 | assembly = Assembly.Load(assemblyName); 42 | } 43 | catch (Exception e) 44 | { 45 | // Whatever caused this exception, the type cannot be loaded, so disregard it as null. 46 | if (e is FileNotFoundException || e is FileLoadException) 47 | return null; 48 | 49 | throw; 50 | } 51 | 52 | string namespaceName = script.GetNamespaceName(); 53 | string fullTypeName = namespaceName == string.Empty ? foundClassName : $"{namespaceName}.{foundClassName}"; 54 | 55 | Type type = assembly.GetType(fullTypeName); 56 | return type; 57 | } 58 | 59 | private static string GetFirstClassFromText(string text) 60 | { 61 | string className = _classRegex.Match(text).Value; 62 | return GetProperClassName(className); 63 | } 64 | 65 | private static string GetFirstClassWithName(string text, string className) 66 | { 67 | string pattern = $@"(?<=(class )|(struct )){className}(\s)?(<.*?>)?(?=(\s|\n)*(:|{{))"; 68 | string foundClassName = Regex.Match(text, pattern).Value; 69 | return GetProperClassName(foundClassName); 70 | } 71 | 72 | private static string GetProperClassName(string rawClassName) 73 | { 74 | if (string.IsNullOrEmpty(rawClassName)) 75 | return rawClassName; 76 | 77 | if ( ! rawClassName.Contains("<")) 78 | return rawClassName; 79 | 80 | int argsCount = rawClassName.CountChars(',') + 1; 81 | int bracketIndex = rawClassName.IndexOf('<'); 82 | return $"{rawClassName.Substring(0, bracketIndex)}`{argsCount.ToString()}"; 83 | } 84 | 85 | /// Returns the assembly name of the class implemented by this script. 86 | /// The script to search for assembly in. 87 | /// 88 | /// The assembly name without the .dll extension, or an empty string if the assembly was not found. 89 | /// 90 | [PublicAPI, NotNull] public static string GetAssemblyName(this MonoScript script) 91 | { 92 | string assemblyName = script.Internal_GetAssemblyName(); 93 | int lastDotIndex = assemblyName.LastIndexOf('.'); 94 | return lastDotIndex == -1 ? string.Empty : assemblyName.Substring(0, lastDotIndex); 95 | } 96 | 97 | private static string GetNamespaceName(this MonoScript asset) 98 | { 99 | string content = asset.text; 100 | Match match = _namespaceNameRegex.Match(content); 101 | return match.Success ? match.Value : string.Empty; 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /Editor/Extensions/MonoScriptExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 39041f030bcb485293bba814af629c4c 3 | timeCreated: 1603189567 -------------------------------------------------------------------------------- /Editor/Extensions/RectExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using JetBrains.Annotations; 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | public static class RectExtensions 8 | { 9 | [PublicAPI] 10 | public static Rect ShiftOneLineDown(this Rect rect, int indent = -1, float lineHeight = 0f) 11 | { 12 | const float paddingBetweenFields = 2f; 13 | const float indentPerLevel = 15f; 14 | 15 | if (lineHeight == 0f) 16 | lineHeight = EditorGUIUtility.singleLineHeight; 17 | 18 | if (indent == -1) 19 | indent = EditorGUI.indentLevel; 20 | 21 | rect.xMin += indent * indentPerLevel; 22 | rect.y += lineHeight + paddingBetweenFields; 23 | 24 | return rect; 25 | } 26 | 27 | [PublicAPI] 28 | public static bool Contains(this Rect rect, Rect otherRect) 29 | { 30 | return rect.xMin <= otherRect.xMin 31 | && rect.yMin <= otherRect.yMin 32 | && rect.xMax >= otherRect.xMax 33 | && rect.yMax >= otherRect.yMax; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Editor/Extensions/RectExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ab17c2ea23f049648431810916d8d392 3 | timeCreated: 1619461280 -------------------------------------------------------------------------------- /Editor/Extensions/SerializedObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | public static class SerializedObjectExtensions 7 | { 8 | public static void SetHideFlagsPersistently(this SerializedObject serializedObject, HideFlags flags) 9 | { 10 | // The only way to set the hide flags persistently. 11 | var hideFlagsProp = serializedObject.FindProperty("m_ObjectHideFlags"); 12 | int flagsValue = (int) flags; 13 | 14 | if (hideFlagsProp.intValue != flagsValue) 15 | { 16 | hideFlagsProp.intValue = flagsValue; 17 | serializedObject.ApplyModifiedProperties(); 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Editor/Extensions/SerializedObjectExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9362bc75c873450c9b2c1eea32a948cd 3 | timeCreated: 1656966800 -------------------------------------------------------------------------------- /Editor/Extensions/SerializedObjectValuesCopier.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System.Collections.Generic; 4 | using Editor; 5 | using JetBrains.Annotations; 6 | using UnityEditor; 7 | using UnityEngine; 8 | 9 | /// 10 | /// Provides methods that allow to copy values from one to another. 11 | /// It works with too. 12 | /// 13 | public static class SerializedObjectValuesCopier 14 | { 15 | /// 16 | /// Copies values of the visible properties from to . 17 | /// 18 | /// Destination object. 19 | /// Source object. 20 | /// Names of properties to exclude from copying. 21 | [PublicAPI] 22 | public static void CopyValuesFrom(this SerializedObject thisSerializedObject, Object otherObject, HashSet excludeValues = null) 23 | { 24 | var otherSerializedObject = new SerializedObject(otherObject); 25 | thisSerializedObject.CopyValuesFrom(otherSerializedObject, excludeValues); 26 | } 27 | 28 | /// 29 | /// Copies values of the visible properties from to . 30 | /// 31 | /// Destination object. 32 | /// Source object. 33 | /// Names of properties to exclude from copying. 34 | [PublicAPI] 35 | public static void CopyValuesFrom(this Object thisObject, Object otherObject, 36 | HashSet excludeValues = null) 37 | { 38 | var thisSerializedObject = new SerializedObject(thisObject); 39 | var otherSerializedObject = new SerializedObject(otherObject); 40 | thisSerializedObject.CopyValuesFrom(otherSerializedObject, excludeValues); 41 | } 42 | 43 | /// 44 | /// Copies values of the visible properties from to . 45 | /// 46 | /// Destination object. 47 | /// Source object. 48 | /// Names of properties to exclude from copying. 49 | [PublicAPI] 50 | public static void CopyValuesFrom(this Object thisObject, SerializedObject otherObject, 51 | HashSet excludeValues = null) 52 | { 53 | var thisSerializedObject = new SerializedObject(thisObject); 54 | thisSerializedObject.CopyValuesFrom(otherObject, excludeValues); 55 | } 56 | 57 | /// 58 | /// Copies values of the visible properties from to . 59 | /// 60 | /// Destination object. 61 | /// Source object. 62 | /// Names of properties to exclude from copying. 63 | [PublicAPI] 64 | public static void CopyValuesFrom(this SerializedObject thisObject, SerializedObject otherObject, 65 | HashSet excludeValues = null) 66 | { 67 | var otherObjectProps = new ChildProperties(otherObject); 68 | 69 | foreach (SerializedProperty childProperty in otherObjectProps) 70 | { 71 | if (excludeValues?.Contains(childProperty.name) == true) 72 | continue; 73 | 74 | thisObject.CopyFromSerializedPropertyIfDifferent(childProperty); 75 | } 76 | 77 | if (thisObject.hasModifiedProperties) 78 | thisObject.ApplyModifiedProperties(); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /Editor/Extensions/SerializedObjectValuesCopier.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4adec07b984c4ff08915de9dfe7256d3 3 | timeCreated: 1604866076 -------------------------------------------------------------------------------- /Editor/Extensions/SerializedPropertyExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Text.RegularExpressions; 9 | using JetBrains.Annotations; 10 | using SolidUtilities; 11 | using UnityEditor; 12 | using UnityEditorInternals; 13 | using UnityEngine.Assertions; 14 | 15 | /// Different useful extensions for . 16 | [PublicAPI] 17 | public static class SerializedPropertyExtensions 18 | { 19 | /// 20 | /// Checks whether the serialized property is built-in. has a lot of built-in 21 | /// properties and we are often interested only in the custom ones. 22 | /// 23 | /// The property to check. 24 | /// Whether the property is built-in. 25 | public static bool IsBuiltIn(this SerializedProperty property) 26 | { 27 | if (property.name == "size" || property.name == "Array") 28 | return true; 29 | 30 | string firstTwoChars = property.name.Substring(0, 2); 31 | return firstTwoChars == "m_"; 32 | } 33 | 34 | public static SerializedProperty GetParent(this SerializedProperty property) 35 | { 36 | if (!property.propertyPath.Contains('.')) 37 | return null; 38 | 39 | var parentPropertyPath = property.propertyPath.GetSubstringBeforeLast('.'); 40 | if (parentPropertyPath.EndsWith(".Array")) 41 | { 42 | parentPropertyPath = parentPropertyPath.Substring(0, parentPropertyPath.Length - 6); 43 | } 44 | 45 | if (string.IsNullOrEmpty(parentPropertyPath)) 46 | return null; 47 | 48 | return property.serializedObject.FindProperty(parentPropertyPath); 49 | } 50 | 51 | /// Gets type of the object serialized by the . 52 | /// The property whose type to find. 53 | /// Type of the object serialized by . 54 | [NotNull, PublicAPI] 55 | public static Type GetObjectType(this SerializedProperty property) => property.GetFieldInfoAndType().Type; 56 | 57 | [PublicAPI] 58 | public static FieldInfo GetFieldInfo(this SerializedProperty property) => property.GetFieldInfoAndType().FieldInfo; 59 | 60 | public static T GetObject(this SerializedProperty property) => (T) property.GetObject(); 61 | 62 | public static object GetObject(this SerializedProperty property) 63 | { 64 | var propertyPaths = property.propertyPath.Split('.'); 65 | 66 | var currentProperty = property.serializedObject.FindProperty(propertyPaths[0]); 67 | var fieldInfo = currentProperty.GetFieldInfo(); 68 | object target = fieldInfo.GetValue(property.serializedObject.targetObject); 69 | 70 | foreach (string path in propertyPaths.Skip(1)) 71 | { 72 | if (path == "Array") 73 | { 74 | continue; 75 | } 76 | 77 | if (path.StartsWith("data[")) 78 | { 79 | int index = int.Parse(path[5].ToString()); 80 | currentProperty = currentProperty.GetArrayElementAtIndex(index); 81 | target = ((IList) target)[index]; 82 | } 83 | else 84 | { 85 | currentProperty = currentProperty.FindPropertyRelative(path); 86 | fieldInfo = currentProperty.GetFieldInfo(); 87 | target = fieldInfo.GetValue(target); 88 | } 89 | } 90 | 91 | return target; 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /Editor/Extensions/SerializedPropertyExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bb77f7ccf3574b2db1842e9c17460ec2 3 | timeCreated: 1598981882 -------------------------------------------------------------------------------- /Editor/Helpers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f18356641e51564590f173bc15a9a03 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Helpers/AssemblyGeneration.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System.IO; 4 | using System.Text; 5 | using UnityEditor; 6 | 7 | /// 8 | /// A class responsible for importing a generated DLL with appropriate settings. 9 | /// 10 | public static class AssemblyGeneration 11 | { 12 | public static void ImportAssemblyAsset(string assemblyPath, string assemblyGUID, bool editorOnly = false, bool excludeEditor = false) 13 | { 14 | // Sometimes, we need to know GUID of a future DLL before we start creating and importing it. 15 | // That's why it's passed as a parameter. 16 | string metaContent = editorOnly ? GetEditorMetaContent(assemblyGUID) : GetMetaFileContent(assemblyGUID, excludeEditor); 17 | 18 | // Starting from Unity 2019, .meta files are hidden and their direct editing via File.WriteAllText can 19 | // raise exceptions. Operating on a file through FileStream is safer and allows to be sure the file will be 20 | // edited without issues. 21 | using (var fs = new FileStream($"{assemblyPath}.meta", FileMode.Create)) 22 | { 23 | using (TextWriter tw = new StreamWriter(fs, Encoding.UTF8, 1024, true)) 24 | { 25 | tw.Write(metaContent); 26 | } 27 | 28 | fs.SetLength(fs.Position); 29 | } 30 | 31 | AssetDatabase.ImportAsset(assemblyPath); 32 | } 33 | 34 | private static string GetMetaFileContent(string guid, bool excludeEditor) 35 | { 36 | // Auto Reference is disabled, Validate References is disabled, all platforms are enabled, and Any CPU/OS is chosen for all platforms. 37 | return $@"fileFormatVersion: 2 38 | guid: {guid} 39 | PluginImporter: 40 | externalObjects: {{}} 41 | serializedVersion: 2 42 | iconMap: {{}} 43 | executionOrder: {{}} 44 | defineConstraints: [] 45 | isPreloaded: 0 46 | isOverridable: 0 47 | isExplicitlyReferenced: 1 48 | validateReferences: 0 49 | platformData: 50 | - first: 51 | : Any 52 | second: 53 | enabled: 0 54 | settings: 55 | Exclude Editor: {(excludeEditor ? "1" : "0")} 56 | Exclude Linux64: 0 57 | Exclude OSXUniversal: 0 58 | Exclude Win: 0 59 | Exclude Win64: 0 60 | - first: 61 | Any: 62 | second: 63 | enabled: 1 64 | settings: {{}} 65 | - first: 66 | Editor: Editor 67 | second: 68 | enabled: 1 69 | settings: 70 | CPU: AnyCPU 71 | DefaultValueInitialized: true 72 | OS: AnyOS 73 | - first: 74 | Standalone: Linux64 75 | second: 76 | enabled: 1 77 | settings: 78 | CPU: AnyCPU 79 | - first: 80 | Standalone: OSXUniversal 81 | second: 82 | enabled: 1 83 | settings: 84 | CPU: AnyCPU 85 | - first: 86 | Standalone: Win 87 | second: 88 | enabled: 1 89 | settings: 90 | CPU: x86 91 | - first: 92 | Standalone: Win64 93 | second: 94 | enabled: 1 95 | settings: 96 | CPU: x86_64 97 | - first: 98 | Windows Store Apps: WindowsStoreApps 99 | second: 100 | enabled: 0 101 | settings: 102 | CPU: AnyCPU 103 | userData: 104 | assetBundleName: 105 | assetBundleVariant: 106 | "; 107 | } 108 | 109 | private static string GetEditorMetaContent(string guid) 110 | { 111 | // Auto Reference is disabled, Validate References is disabled, only Editor platform is enabled. 112 | return $@"fileFormatVersion: 2 113 | guid: {guid} 114 | PluginImporter: 115 | externalObjects: {{}} 116 | serializedVersion: 2 117 | iconMap: {{}} 118 | executionOrder: {{}} 119 | defineConstraints: [] 120 | isPreloaded: 0 121 | isOverridable: 0 122 | isExplicitlyReferenced: 1 123 | validateReferences: 0 124 | platformData: 125 | - first: 126 | : Any 127 | second: 128 | enabled: 0 129 | settings: 130 | Exclude Editor: 0 131 | Exclude Linux64: 1 132 | Exclude OSXUniversal: 1 133 | Exclude Win: 1 134 | Exclude Win64: 1 135 | - first: 136 | Any: 137 | second: 138 | enabled: 0 139 | settings: {{}} 140 | - first: 141 | Editor: Editor 142 | second: 143 | enabled: 1 144 | settings: 145 | CPU: AnyCPU 146 | DefaultValueInitialized: true 147 | OS: AnyOS 148 | - first: 149 | Standalone: Linux64 150 | second: 151 | enabled: 0 152 | settings: 153 | CPU: None 154 | - first: 155 | Standalone: OSXUniversal 156 | second: 157 | enabled: 0 158 | settings: 159 | CPU: None 160 | - first: 161 | Standalone: Win 162 | second: 163 | enabled: 0 164 | settings: 165 | CPU: None 166 | - first: 167 | Standalone: Win64 168 | second: 169 | enabled: 0 170 | settings: 171 | CPU: None 172 | - first: 173 | Windows Store Apps: WindowsStoreApps 174 | second: 175 | enabled: 0 176 | settings: 177 | CPU: AnyCPU 178 | userData: 179 | assetBundleName: 180 | assetBundleVariant: 181 | "; 182 | } 183 | } 184 | } -------------------------------------------------------------------------------- /Editor/Helpers/AssemblyGeneration.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b2ab1a0977b44bc9a91584242e992a67 3 | timeCreated: 1609241018 -------------------------------------------------------------------------------- /Editor/Helpers/AssetDatabaseHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using Editor; 5 | using JetBrains.Annotations; 6 | using UnityEditor; 7 | 8 | public static class AssetDatabaseHelper 9 | { 10 | /// 11 | /// Retrieves type of the class located in an asset with the matching . 12 | /// 13 | /// The GUID of an asset to search for. 14 | /// Type of the class located in an asset with the matching . 15 | [PublicAPI, CanBeNull, Pure] 16 | public static Type GetTypeFromGUID(string guid) 17 | { 18 | string assetPath = AssetDatabase.GUIDToAssetPath(guid); 19 | 20 | if (string.IsNullOrEmpty(assetPath)) 21 | return null; 22 | 23 | var script = AssetDatabase.LoadAssetAtPath(assetPath); 24 | 25 | return script == null ? null : script.GetClassType(); 26 | } 27 | 28 | /// 29 | /// Returns a unique GUID that is known to have no conflicts with the existing assets, so that you create a new asset manually. 30 | /// 31 | /// A unique asset GUID. 32 | public static string GetUniqueGUID() 33 | { 34 | GUID newGUID; 35 | 36 | do 37 | { 38 | newGUID = GUID.Generate(); 39 | } 40 | while ( ! string.IsNullOrEmpty(AssetDatabase.GUIDToAssetPath(newGUID.ToString()))); 41 | 42 | return newGUID.ToString(); 43 | } 44 | 45 | /// 46 | /// Completely prevents AssetDatabase from importing assets or refreshin. 47 | /// 48 | /// Instance of a disposable struct. 49 | [PublicAPI] 50 | public static DisabledAssetDatabase DisabledScope() => new DisabledAssetDatabase(default); 51 | 52 | /// 53 | /// Completely prevents AssetDatabase from importing assets or refreshing. 54 | /// 55 | public readonly struct DisabledAssetDatabase : IDisposable 56 | { 57 | public DisabledAssetDatabase(bool _) 58 | { 59 | EditorApplication.LockReloadAssemblies(); 60 | AssetDatabase.DisallowAutoRefresh(); 61 | AssetDatabase.StartAssetEditing(); 62 | } 63 | 64 | public void Dispose() 65 | { 66 | AssetDatabase.StopAssetEditing(); 67 | AssetDatabase.AllowAutoRefresh(); 68 | EditorApplication.UnlockReloadAssemblies(); 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /Editor/Helpers/AssetDatabaseHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: af85c90953fb43a9ba52a80d34cdc9b5 3 | timeCreated: 1608128678 -------------------------------------------------------------------------------- /Editor/Helpers/AssetHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using Editor; 5 | using JetBrains.Annotations; 6 | using SolidUtilities; 7 | using UnityEditor; 8 | 9 | public static class AssetHelper 10 | { 11 | /// 12 | /// Gets the GUID of an asset where the type is located. 13 | /// 14 | /// Type to search for in assets. 15 | /// GUID of the asset where the type is located, or null if the asset was not found. 16 | /// MonoScript of the asset where the type is located, or null if the asset was not found. 17 | /// true if the asset with the specified type was found. 18 | [PublicAPI] 19 | [ContractAnnotation("=> true, GUID: notnull; => false, GUID: null")] 20 | public static bool GetAssetDetails(Type type, [CanBeNull] out string GUID, out MonoScript monoScript) 21 | { 22 | GUID = string.Empty; 23 | monoScript = null; 24 | 25 | if (type == null) 26 | return false; 27 | 28 | if (type.IsGenericType) 29 | type = type.GetGenericTypeDefinition(); 30 | 31 | string typeNameWithoutSuffix = type.Name.StripGenericSuffix(); 32 | 33 | foreach (string guid in AssetDatabase.FindAssets($"t:MonoScript {typeNameWithoutSuffix}")) 34 | { 35 | string assetPath = AssetDatabase.GUIDToAssetPath(guid); 36 | var asset = AssetDatabase.LoadAssetAtPath(assetPath); 37 | 38 | if (asset is null || asset.GetClassType(typeNameWithoutSuffix) != type) 39 | continue; 40 | 41 | GUID = guid; 42 | monoScript = asset; 43 | return true; 44 | } 45 | 46 | return false; 47 | } 48 | 49 | [NotNull] 50 | public static string GetClassGUID(Type type) => 51 | GetAssetDetails(type, out string guid, out MonoScript _) ? guid : string.Empty; 52 | 53 | public static MonoScript GetMonoScriptFromType(Type type) 54 | { 55 | GetAssetDetails(type, out string _, out MonoScript monoScript); 56 | return monoScript; 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /Editor/Helpers/AssetHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34ce9e8e6a804157a273a7f00431b1a9 3 | timeCreated: 1606838627 -------------------------------------------------------------------------------- /Editor/Helpers/ChildProperties.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using Editor; 7 | using JetBrains.Annotations; 8 | using UnityEditor; 9 | 10 | /// 11 | /// Allows iterating over child properties of a serialized object without entering nested properties. 12 | /// 13 | /// 14 | /// var childProperties = new ChildProperties(serializedObject); 15 | /// foreach (var child in childProperties) 16 | /// { 17 | /// FieldInfo field = targetType.GetFieldAtPath(child.propertyPath); 18 | /// Draw(field); 19 | /// } 20 | /// 21 | [PublicAPI] public class ChildProperties : IEnumerator, IEnumerable 22 | { 23 | private readonly SerializedObject _parentObject; 24 | private readonly bool _enterChildren; 25 | private readonly bool _excludeBuiltInProperties; 26 | private readonly bool _visibleOnly; 27 | 28 | private SerializedProperty _currentProp; 29 | private bool _nextPropertyExists; 30 | 31 | /// 32 | /// Initializes a new instance of the class. 33 | /// 34 | /// The parent serialized object which child properties you want to inspect. 35 | /// Whether to iterate through child properties recursively. false by default. 36 | /// Whether to exclude built-in properties from the iteration. true by default. 37 | /// Whether to iterate only over the visible properties. 38 | public ChildProperties(SerializedObject parentObject, bool enterChildren = false, bool excludeBuiltInProperties = true, bool visibleOnly = true) 39 | { 40 | _parentObject = parentObject; 41 | _enterChildren = enterChildren; 42 | _excludeBuiltInProperties = excludeBuiltInProperties; 43 | _visibleOnly = visibleOnly; 44 | } 45 | 46 | SerializedProperty IEnumerator.Current => _currentProp; 47 | 48 | object IEnumerator.Current => _currentProp; 49 | 50 | bool IEnumerator.MoveNext() 51 | { 52 | if ( ! _nextPropertyExists) 53 | return false; 54 | 55 | _nextPropertyExists = _currentProp.Next(_enterChildren, _visibleOnly); 56 | 57 | if (_excludeBuiltInProperties) 58 | { 59 | while (_nextPropertyExists && _currentProp.IsBuiltIn()) 60 | _nextPropertyExists = _currentProp.Next(_enterChildren, _visibleOnly); 61 | } 62 | 63 | return _nextPropertyExists; 64 | } 65 | 66 | public void Reset() 67 | { 68 | _currentProp = _parentObject.GetIterator(); 69 | _nextPropertyExists = _currentProp.Next(true); 70 | } 71 | 72 | void IDisposable.Dispose() { } 73 | 74 | IEnumerator IEnumerable.GetEnumerator() 75 | { 76 | Reset(); 77 | return this; 78 | } 79 | 80 | IEnumerator IEnumerable.GetEnumerator() 81 | { 82 | Reset(); 83 | return this; 84 | } 85 | } 86 | 87 | internal static class PropertyExtensions 88 | { 89 | public static bool Next(this SerializedProperty prop, bool enterChildren, bool visible) 90 | { 91 | return visible ? prop.NextVisible(enterChildren) : prop.Next(enterChildren); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /Editor/Helpers/ChildProperties.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ace900824b9c418a8529e9fd144d4ff4 3 | timeCreated: 1598984707 -------------------------------------------------------------------------------- /Editor/Helpers/DrawerReplacer.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using JetBrains.Annotations; 4 | using UnityEditor; 5 | 6 | public static class DrawerReplacer 7 | { 8 | /// 9 | /// Replaces the default for with a custom one. 10 | /// 11 | /// 12 | /// The type of object to use the custom for. 13 | /// 14 | /// 15 | /// The type of custom to use for . 16 | /// 17 | /// 18 | /// public class CustomUnityEventDrawer : PropertyDrawer 19 | /// { 20 | /// [DidReloadScripts] 21 | /// private static void ReplaceDefaultDrawer() 22 | /// => DrawerReplacer.ReplaceDefaultDrawer<UnityEventBase, CustomUnityEventDrawer>(); 23 | /// 24 | /// public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { } 25 | /// } 26 | /// 27 | [PublicAPI] 28 | public static void ReplaceDefaultDrawer() 29 | where TDrawer : PropertyDrawer 30 | { 31 | UnityEditorInternals.DrawerReplacer.ReplaceDefaultDrawer(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Editor/Helpers/DrawerReplacer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a17bd73caf924ab2b9b29b22f4df8cd5 3 | timeCreated: 1614588692 -------------------------------------------------------------------------------- /Editor/Helpers/EditorDrawHelper.MixedValue.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using UnityEditor; 6 | 7 | public static partial class EditorDrawHelper 8 | { 9 | /// Sets to the needed value temporarily. 10 | /// 11 | /// using (new EditorDrawHelper.MixedValue(true)) 12 | /// { 13 | /// DrawTypeSelectionControl(); 14 | /// } 15 | /// 16 | [PublicAPI] 17 | public readonly struct MixedValue : IDisposable 18 | { 19 | private readonly bool _previousValue; 20 | 21 | /// Sets to the needed value temporarily. 22 | /// Whether to show mixed value. 23 | /// 24 | /// using (new EditorDrawHelper.MixedValue(true)) 25 | /// { 26 | /// DrawTypeSelectionControl(); 27 | /// } 28 | /// 29 | public MixedValue(bool showMixedValue) 30 | { 31 | _previousValue = EditorGUI.showMixedValue; 32 | EditorGUI.showMixedValue = showMixedValue; 33 | } 34 | 35 | public void Dispose() 36 | { 37 | EditorGUI.showMixedValue = _previousValue; 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Editor/Helpers/EditorDrawHelper.MixedValue.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41a55f870d424e7c9ffea76675850a9d 3 | timeCreated: 1610624367 -------------------------------------------------------------------------------- /Editor/Helpers/EditorDrawHelper.PropertyWrapper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using UnityEditor; 6 | using UnityEngine; 7 | 8 | public static partial class EditorDrawHelper 9 | { 10 | /// 11 | /// Draws content in a property wrapper, useful for making regular GUI controls work with SerializedProperty. 12 | /// 13 | [PublicAPI] 14 | public readonly struct PropertyWrapper : IDisposable 15 | { 16 | private readonly GUIContent _label; 17 | 18 | /// 19 | /// Draws content in a property wrapper, useful for making regular GUI controls work with SerializedProperty. 20 | /// 21 | /// Rectangle on the screen to use for the control, including label if applicable. 22 | /// Optional label in front of the slider. Use null to use the name from the 23 | /// SerializedProperty. Use GUIContent.none to not display a label. 24 | /// The SerializedProperty to use for the control. 25 | public PropertyWrapper(Rect position, GUIContent label, SerializedProperty property) 26 | { 27 | _label = EditorGUI.BeginProperty(position, label, property); 28 | } 29 | 30 | public static implicit operator GUIContent(PropertyWrapper wrapper) => wrapper._label; 31 | 32 | public void Dispose() 33 | { 34 | EditorGUI.EndProperty(); 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Editor/Helpers/EditorDrawHelper.PropertyWrapper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6acd38b261c14f3e9b636eb37f22c8ac 3 | timeCreated: 1610624361 -------------------------------------------------------------------------------- /Editor/Helpers/EditorDrawHelper.SearchToolbarStyle.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using SolidUtilities; 6 | using UnityEditor; 7 | using UnityEngine; 8 | 9 | public static partial class EditorDrawHelper 10 | { 11 | /// Applies the search toolbar style to the stuff that will be drawn inside. 12 | /// 13 | /// using (new EditorDrawHelper.SearchToolbarStyle(DropdownStyle.SearchToolbarHeight)) 14 | /// { 15 | /// DrawSearchToolbar(); 16 | /// } 17 | /// 18 | [PublicAPI] 19 | public readonly struct SearchToolbarStyle : IDisposable 20 | { 21 | private static readonly GUILayoutOption[] _options = { GUILayoutHelper.ExpandWidth(false), null }; 22 | private static GUIStyle _style; 23 | 24 | private static GUIStyle Style => 25 | _style ?? (_style = new GUIStyle(EditorStyles.toolbar) 26 | { 27 | padding = new RectOffset(0, 0, 0, 0), 28 | stretchHeight = true, 29 | stretchWidth = true, 30 | fixedHeight = 0f 31 | }); 32 | 33 | /// Applies the search toolbar style to the stuff that will be drawn inside. 34 | /// Height of the toolbar. 35 | /// 36 | /// using (new EditorDrawHelper.SearchToolbarStyle(DropdownStyle.SearchToolbarHeight)) 37 | /// { 38 | /// DrawSearchToolbar(); 39 | /// } 40 | /// 41 | public SearchToolbarStyle(float toolbarHeight) 42 | { 43 | _options[1] = GUILayout.Height(toolbarHeight); 44 | 45 | EditorGUILayout.BeginHorizontal( 46 | Style, 47 | _options); 48 | } 49 | 50 | public void Dispose() 51 | { 52 | EditorGUILayout.EndHorizontal(); 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /Editor/Helpers/EditorDrawHelper.SearchToolbarStyle.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c008953b7e6b4b21ba2c4083662e1a99 3 | timeCreated: 1610624352 -------------------------------------------------------------------------------- /Editor/Helpers/EditorGUIHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using UnityEditor; 6 | using UnityEngine; 7 | 8 | public static class EditorGUIHelper 9 | { 10 | private static GUIStyle _placeholderStyle; 11 | 12 | private static GUIStyle PlaceholderStyle => 13 | _placeholderStyle ?? (_placeholderStyle = new GUIStyle(EditorStyles.centeredGreyMiniLabel) 14 | { 15 | alignment = TextAnchor.MiddleLeft, 16 | clipping = TextClipping.Clip, 17 | margin = new RectOffset(4, 4, 4, 4) 18 | }); 19 | 20 | [PublicAPI] 21 | public static bool HasKeyboardFocus(int controlID) => UnityEditorInternals.EditorGUIProxy.HasKeyboardFocus(controlID); 22 | 23 | public static IndentLevel IndentLevelBlock(int indentLevel) => new IndentLevel(indentLevel); 24 | 25 | public readonly struct IndentLevel : IDisposable 26 | { 27 | private readonly int _previousIndentLevel; 28 | 29 | public IndentLevel(int indentLevel) 30 | { 31 | _previousIndentLevel = EditorGUI.indentLevel; 32 | EditorGUI.indentLevel = indentLevel; 33 | } 34 | 35 | public void Dispose() 36 | { 37 | EditorGUI.indentLevel = _previousIndentLevel; 38 | } 39 | } 40 | 41 | /// Draws borders with a given color and width around a rectangle. 42 | /// Width of the rectangle. 43 | /// Height of the rectangle. 44 | /// Color of the borders. 45 | /// Width of the borders. 46 | /// 47 | /// EditorDrawHelper.DrawBorders(position.width, position.height, DropdownStyle.BorderColor); 48 | /// 49 | [PublicAPI] public static void DrawBorders(float rectWidth, float rectHeight, Color color, float borderWidth = 1f) 50 | { 51 | if (Event.current.type != EventType.Repaint) 52 | return; 53 | 54 | var leftBorder = new Rect(0f, 0f, borderWidth, rectHeight); 55 | var topBorder = new Rect(0f, 0f, rectWidth, borderWidth); 56 | var rightBorder = new Rect(0f, 0f, rectWidth, borderWidth); 57 | var bottomBorder = new Rect(0f, rectHeight - borderWidth, rectWidth, borderWidth); 58 | 59 | EditorGUI.DrawRect(leftBorder, color); 60 | EditorGUI.DrawRect(topBorder, color); 61 | EditorGUI.DrawRect(rightBorder, color); 62 | EditorGUI.DrawRect(bottomBorder, color); 63 | } 64 | 65 | /// Draws content and checks if it was changed. 66 | /// Action that draws the content. 67 | /// Whether the content was changed. 68 | /// 69 | /// bool changed = EditorDrawHelper.CheckIfChanged(() => 70 | /// { 71 | /// _searchString = DrawSearchField(innerToolbarArea, _searchString); 72 | /// }); 73 | /// 74 | [Pure, PublicAPI] public static bool CheckIfChanged(Action drawContent) 75 | { 76 | EditorGUI.BeginChangeCheck(); 77 | drawContent(); 78 | return EditorGUI.EndChangeCheck(); 79 | } 80 | 81 | /// Draws a text field that is always focused. 82 | /// Rectangle to draw the field in. 83 | /// The text to show in the field. 84 | /// Placeholder to show if the field is empty. 85 | /// Style to draw the field with. 86 | /// Unique control name of the field. 87 | /// The text that was written to the field. 88 | /// 89 | /// searchText = EditorDrawHelper.FocusedTextField(searchFieldArea, searchText, "Search", 90 | /// DropdownStyle.SearchToolbarStyle, _searchFieldControlName); 91 | /// 92 | [PublicAPI] public static string FocusedTextField(Rect rect, string text, string placeholder, GUIStyle style, string controlName) 93 | { 94 | const float placeholderIndent = 14f; 95 | 96 | GUI.SetNextControlName(controlName); 97 | text = EditorGUI.TextField(rect, text, style); 98 | EditorGUI.FocusTextInControl(controlName); 99 | 100 | if (Event.current.type == EventType.Repaint && string.IsNullOrEmpty(text)) 101 | { 102 | var placeHolderArea = new Rect(rect.x + placeholderIndent, rect.y, rect.width - placeholderIndent, rect.height); 103 | GUI.Label(placeHolderArea, GUIContentHelper.Temp(placeholder), PlaceholderStyle); 104 | } 105 | 106 | return text; 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /Editor/Helpers/EditorGUIHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 99aa958ef6534b1d8b4a2edaf936fc0d 3 | timeCreated: 1626542156 -------------------------------------------------------------------------------- /Editor/Helpers/EditorGUILayoutHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8c7655332d8c4e4eac47a3c89140e409 3 | timeCreated: 1626542163 -------------------------------------------------------------------------------- /Editor/Helpers/EditorGUIUtilityHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using UnityEditor; 6 | using UnityEngine; 7 | 8 | public static class EditorGUIUtilityHelper 9 | { 10 | public static LabelWidth LabelWidthBlock(float width) => new LabelWidth(width); 11 | 12 | public readonly struct LabelWidth : IDisposable 13 | { 14 | private readonly float _oldWidth; 15 | 16 | public LabelWidth(float width) 17 | { 18 | _oldWidth = EditorGUIUtility.labelWidth; 19 | EditorGUIUtility.labelWidth = width; 20 | } 21 | 22 | public void Dispose() 23 | { 24 | EditorGUIUtility.labelWidth = _oldWidth; 25 | } 26 | } 27 | 28 | /// 29 | /// Returns the same value as if one screen is used. Returns the 30 | /// sum of two screens' widths when two monitors are used and Unity is located on the second screen. It will 31 | /// only return the incorrect value when Unity is located on the second screen and is not fullscreen. 32 | /// 33 | /// 34 | /// Screen width if one monitor is used, or sum of screen widths if multiple monitors are used. 35 | /// 36 | /// 37 | /// always returns 1 in Editor, so there is no way to check the resolution of 38 | /// both monitors. This method uses a workaround but it does not work correctly when Unity is on the second 39 | /// screen and is not fullscreen. Any help to overcome this issue will be appreciated. 40 | /// 41 | [PublicAPI, Pure] 42 | public static float GetScreenWidth() 43 | { 44 | return Mathf.Max(GetMainWindowPosition().xMax, Screen.currentResolution.width); 45 | } 46 | 47 | /// 48 | /// Returns the rectangle of the main Unity window. 49 | /// 50 | /// Rectangle of the main Unity window. 51 | /// 52 | /// For Unity 2020.1 and above, this is just a wrapper of , 53 | /// but below 2020.1 this is a separate solution. 54 | /// 55 | [PublicAPI, Pure] 56 | public static Rect GetMainWindowPosition() 57 | { 58 | #if UNITY_2020_1_OR_NEWER 59 | return EditorGUIUtility.GetMainWindowPosition(); 60 | #else 61 | return EditorGUIUtilityProxy.GetMainWindowPosition(); 62 | #endif 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /Editor/Helpers/EditorGUIUtilityHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1506f0d9305146e685a6403e4d098aa8 3 | timeCreated: 1626542146 -------------------------------------------------------------------------------- /Editor/Helpers/EditorHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using System.Reflection; 5 | using JetBrains.Annotations; 6 | using UnityEditor; 7 | using UnityEngine; 8 | using UnityEngine.Assertions; 9 | using Object = UnityEngine.Object; 10 | 11 | public static class EditorHelper 12 | { 13 | /// Creates an editor of type for . 14 | /// Target object to create an editor for. 15 | /// Type of the editor to create. 16 | /// Editor of type . 17 | [PublicAPI, Pure] 18 | public static T CreateEditor(Object targetObject) 19 | where T : Editor 20 | { 21 | return (T) Editor.CreateEditor(targetObject, typeof(T)); 22 | } 23 | 24 | private static Func _getCurrentMousePosition; 25 | 26 | /// 27 | /// Returns the current mouse position in screen coordinates. Unlike Event.current.mousePosition, it is window-agnostic and always returns the correct screen coordinates. 28 | /// 29 | /// The current mouse position in screen coordinates. 30 | public static Vector2 GetCurrentMousePosition() 31 | { 32 | if (_getCurrentMousePosition == null) 33 | { 34 | var currentMousePositionMethod = typeof(Editor).GetMethod("GetCurrentMousePosition", BindingFlags.NonPublic | BindingFlags.Static); 35 | Assert.IsNotNull(currentMousePositionMethod); 36 | _getCurrentMousePosition = (Func) Delegate.CreateDelegate(typeof(Func), currentMousePositionMethod); 37 | } 38 | 39 | return _getCurrentMousePosition(); 40 | } 41 | 42 | private static Action _forceRebuildInspectors; 43 | public static void ForceRebuildInspectors() 44 | { 45 | if (_forceRebuildInspectors == null) 46 | { 47 | var rebuildMethod = typeof(EditorUtility).GetMethod("ForceRebuildInspectors", 48 | BindingFlags.NonPublic | BindingFlags.Static); 49 | 50 | _forceRebuildInspectors = (Action) Delegate.CreateDelegate(typeof(Action), rebuildMethod); 51 | } 52 | 53 | _forceRebuildInspectors(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /Editor/Helpers/EditorHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3300de4ab6354128bd4a1980dca3bbc4 3 | timeCreated: 1626542135 -------------------------------------------------------------------------------- /Editor/Helpers/EditorIcons.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using SolidUtilities; 4 | using UnityEditor; 5 | using UnityEngine; 6 | using UnityEngine.Assertions; 7 | 8 | /// 9 | /// Collection of icons to use for creating custom inspectors and drawers. Icons can have different tints 10 | /// depending on their state: active, highlighted, etc. 11 | /// 12 | /// 13 | /// var messageContent = new GUIContent(message, EditorIcons.Info); 14 | /// EditorIcon triangleIcon = Expanded ? EditorIcons.TriangleDown : EditorIcons.TriangleRight; 15 | /// 16 | public static class EditorIcons 17 | { 18 | /// 19 | /// Scriptable object that holds references to textures, materials, and other resources used in . 20 | /// 21 | internal static readonly EditorIconsDatabase Database = GetDatabase(); 22 | 23 | /// The default Unity info icon. 24 | public static readonly Texture2D Info = (Texture2D) EditorGUIUtility.Load("console.infoicon"); 25 | 26 | public static readonly Texture2D Error = (Texture2D) EditorGUIUtility.Load("console.erroricon"); 27 | 28 | /// Triangle with one of the vertices looking to the right. Useful in foldout menus. 29 | public static EditorIcon TriangleRight => GetEditorIcon(ref _triangleRight, EditorIconsDatabase.TriangleRight); 30 | private static EditorIcon _triangleRight; 31 | 32 | /// Triangle with one of the vertices looking to the bottom. Useful in foldout menus. 33 | public static EditorIcon TriangleDown 34 | { 35 | get 36 | { 37 | // not using GetEditorIcon here because it would rotate the texture each time the parameter is passed into the method. 38 | if (_triangleDown.Default == null) 39 | { 40 | _triangleDown.Dispose(); 41 | _triangleDown = new EditorIcon(EditorIconsDatabase.TriangleRight.Rotate()); 42 | } 43 | 44 | return _triangleDown; 45 | } 46 | } 47 | private static EditorIcon _triangleDown; 48 | 49 | public static EditorIcon AddButtonS => GetEditorIcon(ref _addButtonS, EditorIconsDatabase.ToolbarPlusS); 50 | private static EditorIcon _addButtonS; 51 | 52 | public static EditorIcon AddButtonI => GetEditorIcon(ref _addButtonI, EditorIconsDatabase.ToolbarPlusI); 53 | private static EditorIcon _addButtonI; 54 | 55 | static EditorIcons() 56 | { 57 | AssemblyReloadEvents.beforeAssemblyReload += DisposeOfEditorIcons; 58 | } 59 | 60 | private static EditorIconsDatabase GetDatabase() 61 | { 62 | const string databaseGuid = "86b4b7622f8a9fc4382b4c179f1e601a"; 63 | string databasePath = AssetDatabase.GUIDToAssetPath(databaseGuid); 64 | var database = AssetDatabase.LoadAssetAtPath(databasePath); 65 | Assert.IsNotNull(database); 66 | return database; 67 | } 68 | 69 | private static void DisposeOfEditorIcons() 70 | { 71 | _triangleRight.Dispose(); 72 | _triangleDown.Dispose(); 73 | _addButtonS.Dispose(); 74 | _addButtonI.Dispose(); 75 | } 76 | 77 | private static EditorIcon GetEditorIcon(ref EditorIcon editorIcon, Texture2D originalIcon) 78 | { 79 | if (editorIcon.Default == null) 80 | { 81 | editorIcon.Dispose(); 82 | editorIcon = new EditorIcon(originalIcon); 83 | } 84 | 85 | return editorIcon; 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /Editor/Helpers/EditorIcons.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 21a7e7d8d8c511d42bbcbaa449799874 3 | timeCreated: 1600420229 -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bad6d003597d4d3408771a00e271ab8d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Active Dark Skin.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Active Dark Skin 11 | m_Shader: {fileID: 4800000, guid: 80482b80e1cd8cb42aa4360de38bb1c5, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.55, g: 0.55, b: 0.55, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | m_BuildTextureStacks: [] 79 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Active Dark Skin.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: afd8a9f771318eb4fa2f59beaff7c586 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Active Light Skin.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Active Light Skin 11 | m_Shader: {fileID: 4800000, guid: 80482b80e1cd8cb42aa4360de38bb1c5, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.4, g: 0.4, b: 0.4, a: 0.69803923} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | m_BuildTextureStacks: [] 79 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Active Light Skin.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee90dc9421b3dc44d964287f916ed291 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Editor Icon Shader.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/EditorIcon" 2 | { 3 | Properties 4 | { 5 | _MainTex("Texture", 2D) = "white" {} 6 | _Color("Color", Color) = (1,1,1,1) 7 | } 8 | SubShader 9 | { 10 | Blend SrcAlpha Zero 11 | Pass 12 | { 13 | CGPROGRAM 14 | #pragma vertex vert 15 | #pragma fragment frag 16 | #include "UnityCG.cginc" 17 | 18 | struct appdata 19 | { 20 | float4 vertex : POSITION; 21 | float2 uv : TEXCOORD0; 22 | }; 23 | 24 | struct v2f 25 | { 26 | float2 uv : TEXCOORD0; 27 | float4 vertex : SV_POSITION; 28 | }; 29 | 30 | sampler2D _MainTex; 31 | float4 _Color; 32 | 33 | v2f vert(appdata v) 34 | { 35 | v2f o; 36 | o.vertex = UnityObjectToClipPos(v.vertex); 37 | o.uv = v.uv; 38 | return o; 39 | } 40 | 41 | fixed4 frag(v2f i) : SV_Target 42 | { 43 | fixed4 col = _Color; 44 | col.a *= tex2D(_MainTex, i.uv).a; 45 | return col; 46 | } 47 | ENDCG 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Editor Icon Shader.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 80482b80e1cd8cb42aa4360de38bb1c5 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Editor Icons Database.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 11500000, guid: 4edf6f6aea69833479ae7500b4bdd8da, type: 3} 13 | m_Name: Editor Icons Database 14 | m_EditorClassIdentifier: 15 | _description: "With this \"database\", EditorIcons class has to hold only one GUID\r\n 16 | reference - to this scriptable object. Every asset-related to editor icons can\r\n 17 | be found here. Also, it allows to swap icons and skins without changing code." 18 | TriangleRight: {fileID: 2800000, guid: bb26edf4be136b0459bfdf7ff0c7455b, type: 3} 19 | _activeDarkSkin: {fileID: 2100000, guid: afd8a9f771318eb4fa2f59beaff7c586, type: 2} 20 | _activeLightSkin: {fileID: 2100000, guid: ee90dc9421b3dc44d964287f916ed291, type: 2} 21 | _highlightedDarkSkin: {fileID: 2100000, guid: 62fb3eb881fc0a345bf6ecb6cf403fd9, type: 2} 22 | _highlightedLightSkin: {fileID: 2100000, guid: 4e4d317484a3c6f40a42c5f3db79ee79, type: 2} 23 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Editor Icons Database.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 86b4b7622f8a9fc4382b4c179f1e601a 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/EditorIcon.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using Editor; 5 | using JetBrains.Annotations; 6 | using UnityEngine; 7 | using Object = UnityEngine.Object; 8 | 9 | /// 10 | /// Icon that can have different tints depending on its state: active, highlighted, etc. Useful for creating custom 11 | /// inspectors and drawers. 12 | /// 13 | [PublicAPI] 14 | public readonly struct EditorIcon : IDisposable 15 | { 16 | /// Icon with the default color. 17 | public readonly Texture2D Default; 18 | 19 | /// Icon with the active state tint. 20 | public readonly Texture2D Active; 21 | 22 | /// Icon with the highlighted state tint. 23 | public readonly Texture2D Highlighted; 24 | 25 | public EditorIcon(Texture2D icon) 26 | { 27 | // This way we can control the lifecycle of the textures ourselves, not fearing that the original texture will be destroyed. 28 | Default = new Texture2D(icon.width, icon.height, icon.format, icon.mipmapCount != 1); 29 | Graphics.CopyTexture(icon, Default); 30 | 31 | Highlighted = null; 32 | Active = null; 33 | 34 | Highlighted = GetIconWithMaterial(EditorIcons.Database.Highlighted); 35 | Active = GetIconWithMaterial(EditorIcons.Database.Active); 36 | } 37 | 38 | private Texture2D GetIconWithMaterial(Material material) 39 | { 40 | Texture2D newTexture = null; 41 | 42 | using (new TextureHelper.SRGBWriteScope(true)) 43 | { 44 | using (var temporary = new TemporaryActiveTexture(Default.width, Default.height, 0)) 45 | { 46 | GL.Clear(false, true, new Color(1f, 1f, 1f, 0f)); 47 | Graphics.Blit(Default, temporary, material); 48 | 49 | newTexture = new Texture2D(Default.width, Default.height, TextureFormat.ARGB32, false, true) 50 | { 51 | filterMode = FilterMode.Bilinear 52 | }; 53 | 54 | newTexture.ReadPixels(new Rect(0.0f, 0.0f, Default.width, Default.height), 0, 0); 55 | newTexture.alphaIsTransparency = true; 56 | newTexture.Apply(); 57 | } 58 | } 59 | 60 | return newTexture; 61 | } 62 | 63 | public void Dispose() 64 | { 65 | Object.DestroyImmediate(Default); 66 | Object.DestroyImmediate(Highlighted); 67 | Object.DestroyImmediate(Active); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/EditorIcon.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: de89e84cb56ef114c9fca76319a2b0f5 3 | timeCreated: 1600344476 -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/EditorIconsDatabase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4edf6f6aea69833479ae7500b4bdd8da 3 | timeCreated: 1600361375 -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Highlighted Dark Skin.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Highlighted Dark Skin 11 | m_Shader: {fileID: 4800000, guid: 80482b80e1cd8cb42aa4360de38bb1c5, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.9, g: 0.9, b: 0.9, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | m_BuildTextureStacks: [] 79 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Highlighted Dark Skin.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 62fb3eb881fc0a345bf6ecb6cf403fd9 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Highlighted Light Skin.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Highlighted Light Skin 11 | m_Shader: {fileID: 4800000, guid: 80482b80e1cd8cb42aa4360de38bb1c5, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.5 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0.4, g: 0.4, b: 0.4, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | m_BuildTextureStacks: [] 79 | -------------------------------------------------------------------------------- /Editor/Helpers/EditorIconsRelated/Highlighted Light Skin.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4e4d317484a3c6f40a42c5f3db79ee79 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Helpers/GUIContentHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using UnityEngine; 4 | 5 | public static class GUIContentHelper 6 | { 7 | private static readonly GUIContent _content = new GUIContent(); 8 | 9 | public static GUIContent Temp(string text, Texture icon = null) 10 | { 11 | _content.text = text; 12 | _content.image = icon; 13 | _content.tooltip = string.Empty; 14 | return _content; 15 | } 16 | 17 | public static GUIContent Temp(string text, string tooltip) 18 | { 19 | _content.text = text; 20 | _content.tooltip = tooltip; 21 | _content.image = null; 22 | return _content; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Editor/Helpers/GUIContentHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 70023abadac24acea56db0bfde320b38 3 | timeCreated: 1626541162 -------------------------------------------------------------------------------- /Editor/Helpers/LogHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using JetBrains.Annotations; 4 | using UnityEditorInternals; 5 | 6 | [PublicAPI] 7 | public enum LogModes 8 | { 9 | /// All user-generated log entries. 10 | UserAll = 0, 11 | 12 | /// Editor-generated errors. 13 | EditorErrors = 1 << 1, 14 | 15 | /// User-generated red log entries (errors, exceptions, assertions). 16 | UserErrorsAndExceptions = 1 << 8, 17 | 18 | /// User and editor-generated warnings. 19 | UserAndEditorWarnings = 1 << 9, 20 | 21 | /// User and editor-generated info messages. 22 | UserAndEditorInfos = 1 << 10, 23 | 24 | /// Mode of the "No script asset for..." warning. 25 | NoScriptAssetWarning = 1 << 18, 26 | 27 | /// User-generated info messages. 28 | UserInfo = UserAndEditorInfos | 1 << 14 | 1 << 23, // it's unknown what 14 and 23 are exactly for. 29 | 30 | /// User-generated warnings. 31 | UserWarning = UserAndEditorWarnings | 1 << 14 | 1 << 23 32 | } 33 | 34 | /// 35 | /// Contains different methods that simplify or extend operations on log entries. 36 | /// 37 | public static class LogHelper 38 | { 39 | /// Removes log entries that match from console. 40 | /// Mode of the log entries to remove. 41 | [PublicAPI] 42 | public static void RemoveLogEntriesByMode(LogModes mode) 43 | { 44 | LogEntry.Internal_RemoveLogEntriesByMode((int) mode); 45 | } 46 | 47 | /// Returns the total number of log entries in the console. 48 | /// Total number of log entries in the console. 49 | [PublicAPI] 50 | public static int GetCount() => LogEntries.GetCount(); 51 | 52 | /// Returns the number of errors in the console. 53 | /// The number of errors in the console. 54 | [PublicAPI] 55 | public static int GetErrorCount() 56 | { 57 | (int errorCount, int _, int _) = LogEntries.GetCountsByType(); 58 | return errorCount; 59 | } 60 | 61 | /// Returns the number of warnings in the console. 62 | /// The number of warnings in the console. 63 | [PublicAPI] 64 | public static int GetWarningCount() 65 | { 66 | (int _, int warningCount, int _) = LogEntries.GetCountsByType(); 67 | return warningCount; 68 | } 69 | 70 | /// Returns the number of info logs in the console. 71 | /// The number of info logs in the console. 72 | [PublicAPI] 73 | public static int GetLogCount() 74 | { 75 | (int _, int _, int logCount) = LogEntries.GetCountsByType(); 76 | return logCount; 77 | } 78 | 79 | /// Returns the number of log entries in the console by type: error logs, warning logs, info logs. 80 | /// The number of log entries in the console by type: error logs, warning logs, info logs. 81 | [PublicAPI] 82 | public static (int errorCount, int warningCount, int logCount) GetCountByType() 83 | => LogEntries.GetCountsByType(); 84 | 85 | /// Removes all logs from the console. 86 | [PublicAPI] 87 | public static void Clear() => LogEntries.Clear(); 88 | } 89 | } -------------------------------------------------------------------------------- /Editor/Helpers/LogHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6d8143f81588460d9f3f813e3e66869e 3 | timeCreated: 1609321201 -------------------------------------------------------------------------------- /Editor/Helpers/PackageSearcher.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System.Linq; 4 | using JetBrains.Annotations; 5 | using UnityEditor; 6 | using UnityEngine; 7 | using PackageInfo = UnityEditor.PackageManager.PackageInfo; 8 | 9 | public static class PackageSearcher 10 | { 11 | /// 12 | /// Finds a package by its or . 13 | /// 14 | /// 15 | /// or of the package to search for. 16 | /// 17 | /// Package Info object of the package or null if the package was not found. 18 | [PublicAPI, CanBeNull] 19 | public static PackageInfo FindPackageByName(string packageName) 20 | { 21 | if (packageName.Substring(0, 4) == "com.") 22 | return PackageInfo.FindForAssetPath($"Packages/{packageName}"); 23 | 24 | return AssetDatabase.FindAssets("package") 25 | .Select(AssetDatabase.GUIDToAssetPath) 26 | .Where(packageJsonPath => AssetDatabase.LoadAssetAtPath(packageJsonPath) != null) 27 | .Select(PackageInfo.FindForAssetPath) 28 | .FirstOrDefault(x => x.displayName == packageName); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Editor/Helpers/PackageSearcher.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 65281b0361fc4dceb2d95e3eb892fa18 3 | timeCreated: 1603451690 -------------------------------------------------------------------------------- /Editor/Helpers/ProjectDependencySearcher.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 581aafafb1cb44ba9a75ca911fb8ea5b 3 | timeCreated: 1647548780 -------------------------------------------------------------------------------- /Editor/Helpers/ProjectWideSearcher.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System.Collections.Generic; 4 | using UnityEditor; 5 | using UnityEditor.SceneManagement; 6 | using UnityEngine; 7 | using UnityEngine.SceneManagement; 8 | 9 | public static class ProjectWideSearcher 10 | { 11 | public static IEnumerable GetSerializedObjectsInProject() 12 | { 13 | foreach (var serializedObject in GetSerializedObjectsFromScenes()) 14 | { 15 | yield return serializedObject; 16 | } 17 | 18 | foreach (var serializedObject in GetSerializedObjectsFromPrefabs()) 19 | { 20 | yield return serializedObject; 21 | } 22 | 23 | foreach (var serializedObject in GetSerializedObjectsFromScriptableObjects()) 24 | { 25 | yield return serializedObject; 26 | } 27 | } 28 | 29 | private static IEnumerable GetSerializedObjectsFromScenes() 30 | { 31 | var sceneGUIDs = AssetDatabase.FindAssets("t:scene", new[] { "Assets" }); 32 | 33 | foreach (string sceneGUID in sceneGUIDs) 34 | { 35 | string scenePath = AssetDatabase.GUIDToAssetPath(sceneGUID); 36 | 37 | var currentScene = SceneManager.GetActiveScene(); 38 | 39 | var scene = currentScene.path == scenePath ? currentScene : EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive); 40 | 41 | var rootGameObjects = scene.GetRootGameObjects(); 42 | 43 | foreach (GameObject rootGameObject in rootGameObjects) 44 | { 45 | if (rootGameObject == null) 46 | continue; 47 | 48 | foreach (var serializedObject in GetSerializedObjectsFromGameObject(rootGameObject)) 49 | { 50 | yield return serializedObject; 51 | } 52 | } 53 | 54 | if (scene != currentScene) 55 | EditorSceneManager.CloseScene(scene, true); 56 | } 57 | } 58 | 59 | private static IEnumerable GetSerializedObjectsFromGameObject(GameObject gameObject) 60 | { 61 | var components = gameObject.GetComponentsInChildren(); 62 | 63 | foreach (Component component in components) 64 | { 65 | if (component == null) 66 | continue; 67 | 68 | var serializedObject = new SerializedObject(component); 69 | yield return serializedObject; 70 | } 71 | } 72 | 73 | private static IEnumerable GetSerializedObjectsFromPrefabs() 74 | { 75 | var prefabGUIDs = AssetDatabase.FindAssets("t:prefab"); 76 | 77 | foreach (var prefabGUID in prefabGUIDs) 78 | { 79 | string prefabPath = AssetDatabase.GUIDToAssetPath(prefabGUID); 80 | 81 | if (string.IsNullOrEmpty(prefabPath)) 82 | continue; 83 | 84 | var rootGameObject = PrefabUtility.LoadPrefabContents(prefabPath); 85 | 86 | if (rootGameObject == null) 87 | continue; 88 | 89 | foreach (var serializedObject in GetSerializedObjectsFromGameObject(rootGameObject)) 90 | { 91 | yield return serializedObject; 92 | } 93 | 94 | PrefabUtility.UnloadPrefabContents(rootGameObject); 95 | } 96 | } 97 | 98 | private static IEnumerable GetSerializedObjectsFromScriptableObjects() 99 | { 100 | var soGUIDs = AssetDatabase.FindAssets("t:ScriptableObject"); 101 | 102 | foreach (string soGUID in soGUIDs) 103 | { 104 | string soPath = AssetDatabase.AssetPathToGUID(soGUID); 105 | 106 | var scriptableObject = AssetDatabase.LoadAssetAtPath(soPath); 107 | 108 | if (scriptableObject == null) 109 | continue; 110 | 111 | yield return new SerializedObject(scriptableObject); 112 | Resources.UnloadAsset(scriptableObject); 113 | } 114 | } 115 | } 116 | } -------------------------------------------------------------------------------- /Editor/Helpers/ProjectWideSearcher.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5acdf54b329435e98ef56886d08df41 3 | timeCreated: 1643311681 -------------------------------------------------------------------------------- /Editor/Helpers/SerializedPropertyHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System.Collections.Generic; 4 | using UnityEditor; 5 | 6 | public static class SerializedPropertyHelper 7 | { 8 | public static IEnumerable FindPropertiesOfType(IEnumerable serializedObjects, string type) 9 | { 10 | foreach (var serializedObject in serializedObjects) 11 | { 12 | foreach (var serializedProperty in FindPropertiesOfType(serializedObject, type)) 13 | { 14 | yield return serializedProperty; 15 | } 16 | } 17 | } 18 | 19 | private static IEnumerable FindPropertiesOfType(SerializedObject serializedObject, string type) 20 | { 21 | var prop = serializedObject.GetIterator(); 22 | 23 | if (!prop.Next(true)) 24 | yield break; 25 | 26 | do 27 | { 28 | if (prop.type.GetSubstringBefore('`') != type) 29 | continue; 30 | 31 | if (prop.isArray) 32 | { 33 | int arrayLength = prop.arraySize; 34 | 35 | for (int i = 0; i < arrayLength; i++) 36 | { 37 | yield return prop.GetArrayElementAtIndex(i); 38 | } 39 | } 40 | else 41 | { 42 | yield return prop; 43 | } 44 | } 45 | while (prop.NextVisible(true)); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Editor/Helpers/SerializedPropertyHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 162e46f8c43f4f379d489b481170877d 3 | timeCreated: 1647548884 -------------------------------------------------------------------------------- /Editor/Helpers/StackTraceHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System.Text.RegularExpressions; 4 | using UnityEditorInternals; 5 | 6 | public static class StackTraceHelper 7 | { 8 | public static string EnvironmentToUnityStyle(string stackTrace) 9 | { 10 | // Remove at at the start of lines 11 | stackTrace = Regex.Replace(stackTrace, @" +at ", string.Empty); 12 | 13 | // Remove the location part of the stack line if there is no reference to a file on disc 14 | stackTrace = Regex.Replace(stackTrace, @" \[0x00000\] in <.*?(?=\n|$)", string.Empty); 15 | 16 | // Replace [0x00000] in with (at 17 | stackTrace = Regex.Replace(stackTrace, @"\[0x\w+?\] in", "(at"); 18 | 19 | // Add a closing parenthese 20 | stackTrace = Regex.Replace(stackTrace, @"(?<=:\d+) ", ")"); 21 | 22 | return stackTrace; 23 | } 24 | 25 | public static string AddLinks(string unityStackTrace) 26 | { 27 | return ConsoleWindowProxy.StacktraceWithHyperlinks(unityStackTrace, 0); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Editor/Helpers/StackTraceHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4a469a1d8cc949779b4bd2988ad09a74 3 | timeCreated: 1626521937 -------------------------------------------------------------------------------- /Editor/Helpers/TemporaryActiveTexture.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using UnityEngine; 6 | 7 | /// 8 | /// Creates a temporary texture, sets it as active in , then removes the changes 9 | /// and sets the previous active texture back automatically. 10 | /// 11 | /// 12 | /// 13 | /// using (var temporaryActiveTexture = new TemporaryActiveTexture(icon.width, icon.height, 0)) 14 | /// { 15 | /// Graphics.Blit(icon, temporary, material); 16 | /// }); 17 | /// 18 | [PublicAPI] 19 | public class TemporaryActiveTexture : IDisposable 20 | { 21 | private readonly RenderTexture _previousActiveTexture; 22 | private readonly TemporaryRenderTexture _value; 23 | 24 | /// 25 | /// Creates a temporary texture, sets it as active in , then removes it 26 | /// and sets the previous active texture back automatically. 27 | /// 28 | /// Width of the temporary texture in pixels. 29 | /// Height of the temporary texture in pixels. 30 | /// Depth buffer of the temporary texture. 31 | /// 32 | /// 33 | /// using (var temporaryActiveTexture = new TemporaryActiveTexture(icon.width, icon.height, 0)) 34 | /// { 35 | /// Graphics.Blit(icon, temporary, material); 36 | /// }); 37 | /// 38 | public TemporaryActiveTexture(int width, int height, int depthBuffer) 39 | { 40 | _previousActiveTexture = RenderTexture.active; 41 | _value = new TemporaryRenderTexture(width, height, depthBuffer); 42 | RenderTexture.active = _value; 43 | } 44 | 45 | public static implicit operator RenderTexture(TemporaryActiveTexture temporaryTexture) => temporaryTexture._value; 46 | 47 | public void Dispose() 48 | { 49 | _value.Dispose(); 50 | RenderTexture.active = _previousActiveTexture; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Editor/Helpers/TemporaryActiveTexture.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a11caf7afc9c460a8f55860e3683a98a 3 | timeCreated: 1610614958 -------------------------------------------------------------------------------- /Editor/Helpers/TemporaryRenderTexture.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using UnityEngine; 6 | 7 | /// Creates a temporary texture that can be used and then removed automatically. 8 | /// 9 | /// 10 | /// using (var temporaryTexture = new TemporaryRenderTexture(icon.width, icon.height, 0)) 11 | /// { 12 | /// Graphics.Blit(icon, temporaryTexture, material); 13 | /// }); 14 | /// 15 | [PublicAPI] 16 | public class TemporaryRenderTexture : IDisposable 17 | { 18 | private readonly RenderTexture _value; 19 | 20 | /// Creates a temporary texture that can be used and then removed automatically. 21 | /// Width of the temporary texture in pixels. 22 | /// Height of the temporary texture in pixels. 23 | /// Depth buffer of the temporary texture. 24 | /// 25 | /// 26 | /// using (var temporaryTexture = new TemporaryRenderTexture(icon.width, icon.height, 0)) 27 | /// { 28 | /// Graphics.Blit(icon, temporaryTexture, material); 29 | /// }); 30 | /// 31 | public TemporaryRenderTexture(int width, int height, int depthBuffer) 32 | { 33 | _value = RenderTexture.GetTemporary(width, height, depthBuffer); 34 | } 35 | 36 | public static implicit operator RenderTexture(TemporaryRenderTexture temporaryRenderTexture) => temporaryRenderTexture._value; 37 | 38 | public void Dispose() 39 | { 40 | RenderTexture.ReleaseTemporary(_value); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Editor/Helpers/TemporaryRenderTexture.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf2ebf704db54a85b17b0af3c9ebbfd0 3 | timeCreated: 1610614965 -------------------------------------------------------------------------------- /Editor/Helpers/TextureHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using UnityEngine; 6 | 7 | /// Helps to create new textures. 8 | public static class TextureHelper 9 | { 10 | /// 11 | /// Temporarily sets to the passed value, then returns it back. 12 | /// 13 | [PublicAPI] 14 | public readonly struct SRGBWriteScope : IDisposable 15 | { 16 | private readonly bool _previousValue; 17 | 18 | /// Temporarily sets to , then executes the action. 19 | /// Temporary value of . 20 | /// 21 | /// using (new SRGBWriteScope(true)) 22 | /// { 23 | /// GL.Clear(false, true, new Color(1f, 1f, 1f, 0f)); 24 | /// Graphics.Blit(Default, temporary, material); 25 | /// }); 26 | /// 27 | public SRGBWriteScope(bool enableWrite) 28 | { 29 | _previousValue = GL.sRGBWrite; 30 | GL.sRGBWrite = enableWrite; 31 | } 32 | 33 | public void Dispose() 34 | { 35 | GL.sRGBWrite = _previousValue; 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Editor/Helpers/TextureHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d67ddbbf3086b3c4ca63ce969ee3db98 3 | timeCreated: 1600427091 -------------------------------------------------------------------------------- /Editor/PropertyDrawers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f005d159e03b76f4891f759edd05185b 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/PropertyDrawers/ReadOnlyDrawer.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor.PropertyDrawers 2 | { 3 | using SolidUtilities; 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | [CustomPropertyDrawer(typeof(ReadOnlyAttribute))] 8 | internal class ReadOnlyDrawer : PropertyDrawer 9 | { 10 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 11 | { 12 | return EditorGUI.GetPropertyHeight(property, label, true); 13 | } 14 | 15 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 16 | { 17 | using (new EditorGUI.DisabledScope(true)) 18 | { 19 | EditorGUI.PropertyField(position, property, label, true); 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Editor/PropertyDrawers/ReadOnlyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 92a92466945914446860b17de2d76d73 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/PropertyDrawers/ResizableTextAreaAttributeDrawer.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities.Editor.PropertyDrawers 2 | { 3 | using System; 4 | using SolidUtilities; 5 | using UnityEditor; 6 | using UnityEngine; 7 | 8 | [CustomPropertyDrawer(typeof(ResizableTextAreaAttribute))] 9 | public class ResizableTextAreaAttributeDrawer : PropertyDrawer 10 | { 11 | private static readonly GUIContent _tempContent = new GUIContent(); 12 | private static GUIStyle _style; 13 | 14 | private float _textAreaHeight; 15 | 16 | private static GUIStyle Style => _style ?? (_style = new GUIStyle(EditorStyles.textField) { wordWrap = true }); 17 | 18 | private static GUIContent TempContent(string text) 19 | { 20 | _tempContent.text = text; 21 | return _tempContent; 22 | } 23 | 24 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 25 | { 26 | float labelHeight = EditorGUIUtility.singleLineHeight; 27 | return labelHeight + _textAreaHeight; 28 | } 29 | 30 | public override void OnGUI(Rect fieldRect, SerializedProperty property, GUIContent label) 31 | { 32 | if (property.type != "string") 33 | throw new ArgumentException($"ResizableTextArea attribute works only with string fields. {property.type} type was used instead."); 34 | 35 | Rect labelRect = new Rect(fieldRect) { height = EditorGUIUtility.singleLineHeight }; 36 | EditorGUI.LabelField(labelRect, label); 37 | 38 | // fieldRect has the correct width only if the event type is repaint. 39 | if (Event.current.type == EventType.Repaint) 40 | _textAreaHeight = Style.CalcHeight(TempContent(property.stringValue), fieldRect.width); 41 | 42 | var textAreaRect = new Rect(fieldRect.x, fieldRect.y + EditorGUIUtility.singleLineHeight, fieldRect.width, _textAreaHeight); 43 | property.stringValue = EditorGUI.TextArea(textAreaRect, property.stringValue, Style); 44 | 45 | if (property.serializedObject.hasModifiedProperties) 46 | property.serializedObject.ApplyModifiedProperties(); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Editor/PropertyDrawers/ResizableTextAreaAttributeDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4fc48fca71bc4672b8dc201a5b50a25a 3 | timeCreated: 1605265743 -------------------------------------------------------------------------------- /Editor/PropertyDrawers/SerializableDictionaryPropertyDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 91da51d02ab9ebc459d80d5965d40d1a 3 | timeCreated: 1492869349 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Editor/SolidUtilities.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SolidUtilities.Editor", 3 | "rootNamespace": "SolidUtilities.Editor", 4 | "references": [ 5 | "SolidUtilities" 6 | ], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [ 14 | "UnityEditorInternals.dll" 15 | ], 16 | "autoReferenced": true, 17 | "defineConstraints": [], 18 | "versionDefines": [], 19 | "noEngineReferences": false 20 | } -------------------------------------------------------------------------------- /Editor/SolidUtilities.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 48d58eaab94e1de429344393b7653b1f 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License modified with Commons Clause Restriction 2 | 3 | Copyright (c) 2020 SolidAlloy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | Commons Clause Restriction 24 | 25 | The Software is provided to you by the Licensor under the License, as defined below, subject to 26 | the following condition. 27 | Without limiting other conditions in the License, the grant of rights under the License will not 28 | include, and the License does not grant to you, the right to Sell the Software. 29 | For purposes of the foregoing, “Sell” means practicing any or all of the rights granted to you 30 | under the License to provide to third parties, for a fee or other consideration (including without 31 | limitation fees for hosting or consulting/ support services related to the Software), a product or 32 | service whose value derives, entirely or substantially, from the functionality of the Software. 33 | Any license notice or attribution required by the License must also include this Commons Cause 34 | License Condition notice. 35 | 36 | For purposes of the clause above, the “Licensor” is SolidAlloy, the “License” is the MIT License and the Software is the SolidUtilities software provided with this 37 | notice. -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b918bf6037a6c38418eb709f2fcec398 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d98bee7a1a430c4c93949727d0609bb 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4efcf655b72d0714e8a59cc16a3a4f5e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Attributes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8f9dccdbed934013b6c0a0347eeaea99 3 | timeCreated: 1603651352 -------------------------------------------------------------------------------- /Runtime/Attributes/ReadOnlyAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using UnityEngine; 4 | 5 | /// Shows a field as disabled preventing it from being changed from the inspector. 6 | public class ReadOnlyAttribute : PropertyAttribute { } 7 | } -------------------------------------------------------------------------------- /Runtime/Attributes/ReadOnlyAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7661b91123214be1a424daf4fc18c753 3 | timeCreated: 1603648517 -------------------------------------------------------------------------------- /Runtime/Attributes/ResizableTextAreaAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using UnityEngine; 5 | 6 | /// 7 | /// Draws text in a wide field with lines wrap and auto-adjusting height. 8 | /// 9 | [AttributeUsage(AttributeTargets.Field)] 10 | public class ResizableTextAreaAttribute : PropertyAttribute { } 11 | } -------------------------------------------------------------------------------- /Runtime/Attributes/ResizableTextAreaAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 66844f6faf0948cb95340e66d6f20f13 3 | timeCreated: 1605182619 -------------------------------------------------------------------------------- /Runtime/Extensions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 53df37d4c45f4eb19ebead91682d14d6 3 | timeCreated: 1600427233 -------------------------------------------------------------------------------- /Runtime/Extensions/CollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System.Collections.Generic; 4 | 5 | public static class ReadonlyCollectionExtensions 6 | { 7 | public static int IndexOf(this IReadOnlyCollection collection, T elementToFind) 8 | { 9 | int i = 0; 10 | 11 | foreach (T element in collection) 12 | { 13 | if (Equals(element, elementToFind)) 14 | return i; 15 | 16 | i++; 17 | } 18 | 19 | return -1; 20 | } 21 | } 22 | 23 | public static class CollectionExtensions 24 | { 25 | public static bool AddIfMissing(this ICollection list, T value) 26 | { 27 | if (list.Contains(value)) 28 | return false; 29 | 30 | list.Add(value); 31 | return true; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Runtime/Extensions/CollectionExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cfa82752bb04420f9c395e4dea10b95e 3 | timeCreated: 1629054210 -------------------------------------------------------------------------------- /Runtime/Extensions/DictionaryExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System.Collections.Generic; 4 | 5 | public static class DictionaryExtensions 6 | { 7 | /// 8 | /// Gets the value associated with the specified and casts it to type . 9 | /// 10 | /// The dictionary to search for the value in. 11 | /// The key of the value to get. 12 | /// 13 | /// When this method returns, contains the value associated with the specified key, if the key is found; 14 | /// otherwise, the default value for the type of the parameter. 15 | /// This parameter is passed uninitialized. 16 | /// 17 | /// Type of the key. 18 | /// Type of the value in the dictionary. 19 | /// Type to cast the value to when returning it. 20 | /// 21 | /// if the contains an element 22 | /// with the specified key; otherwise, . 23 | /// 24 | public static bool TryGetTypedValue(this Dictionary data, TKey key, out TActual value) 25 | where TActual : TValue 26 | { 27 | bool result = data.TryGetValue(key, out TValue tmp); 28 | value = (TActual)tmp; 29 | return result; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Runtime/Extensions/DictionaryExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e60006635a1f40db8cb66e369f7989e9 3 | timeCreated: 1615576680 -------------------------------------------------------------------------------- /Runtime/Extensions/EnumExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | 6 | #if ! CSHARP_7_3_OR_NEWER 7 | using Unity.Collections.LowLevel.Unsafe; 8 | #endif 9 | 10 | public static class EnumExtensions 11 | { 12 | #if CSHARP_7_3_OR_NEWER 13 | public static bool DoesNotContainFlag(this TEnum thisEnum, TEnum flag) where TEnum : unmanaged, Enum 14 | { 15 | unsafe 16 | { 17 | switch (sizeof(TEnum)) 18 | { 19 | case 1: 20 | return (*(byte*)&thisEnum | ~*(byte*)&flag) != byte.MaxValue; 21 | case 2: 22 | return (*(ushort*)&thisEnum | ~*(ushort*)&flag) != ushort.MaxValue; 23 | case 4: 24 | return (*(uint*)&thisEnum | ~*(uint*)&flag) != uint.MaxValue; 25 | case 8: 26 | return (*(ulong*)&thisEnum | ~*(ulong*)&flag) != ulong.MaxValue; 27 | default: 28 | throw new Exception("Size does not match a known Enum backing type."); 29 | } 30 | } 31 | } 32 | #endif 33 | 34 | /// 35 | /// Allocation-less version of that still runs very fast. 36 | /// 37 | /// The enum to check for flags. 38 | /// The flag to search for in . 39 | /// The type of enum. 40 | /// Whether contains the specified . 41 | /// If it was not possible to determine the underlying type of the enum. 42 | /// 43 | /// Taken from here https://forum.unity.com/threads/c-hasaflag-method-extension-how-to-not-create-garbage-allocation.616924/#post-4420699 44 | /// 45 | [PublicAPI] 46 | public static bool ContainsFlag(this TEnum thisEnum, TEnum flag) where TEnum : 47 | #if CSHARP_7_3_OR_NEWER 48 | unmanaged, Enum 49 | #else 50 | struct 51 | #endif 52 | { 53 | unsafe 54 | { 55 | #if CSHARP_7_3_OR_NEWER 56 | switch (sizeof(TEnum)) 57 | { 58 | case 1: 59 | return (*(byte*)&thisEnum & *(byte*)&flag) > 0; 60 | case 2: 61 | return (*(ushort*)&thisEnum & *(ushort*)&flag) > 0; 62 | case 4: 63 | return (*(uint*)&thisEnum & *(uint*)&flag) > 0; 64 | case 8: 65 | return (*(ulong*)&thisEnum & *(ulong*)&flag) > 0; 66 | default: 67 | throw new Exception("Size does not match a known Enum backing type."); 68 | } 69 | #else 70 | switch (UnsafeUtility.SizeOf()) 71 | { 72 | case 1: 73 | { 74 | byte valLhs = 0; 75 | UnsafeUtility.CopyStructureToPtr(ref thisEnum, &valLhs); 76 | byte valRhs = 0; 77 | UnsafeUtility.CopyStructureToPtr(ref flag, &valRhs); 78 | return (valLhs & valRhs) > 0; 79 | } 80 | case 2: 81 | { 82 | ushort valLhs = 0; 83 | UnsafeUtility.CopyStructureToPtr(ref thisEnum, &valLhs); 84 | ushort valRhs = 0; 85 | UnsafeUtility.CopyStructureToPtr(ref flag, &valRhs); 86 | return (valLhs & valRhs) > 0; 87 | } 88 | case 4: 89 | { 90 | uint valLhs = 0; 91 | UnsafeUtility.CopyStructureToPtr(ref thisEnum, &valLhs); 92 | uint valRhs = 0; 93 | UnsafeUtility.CopyStructureToPtr(ref flag, &valRhs); 94 | return (valLhs & valRhs) > 0; 95 | } 96 | case 8: 97 | { 98 | ulong valLhs = 0; 99 | UnsafeUtility.CopyStructureToPtr(ref thisEnum, &valLhs); 100 | ulong valRhs = 0; 101 | UnsafeUtility.CopyStructureToPtr(ref flag, &valRhs); 102 | return (valLhs & valRhs) > 0; 103 | } 104 | default: 105 | throw new Exception("Size does not match a known Enum backing type."); 106 | } 107 | #endif 108 | } 109 | } 110 | } 111 | } -------------------------------------------------------------------------------- /Runtime/Extensions/EnumExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 359183e2e472463a8f4174cc971f069c 3 | timeCreated: 1610881848 -------------------------------------------------------------------------------- /Runtime/Extensions/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using JetBrains.Annotations; 6 | 7 | public static class EnumerableExtensions 8 | { 9 | /// 10 | /// Converts the collection to HashSet. 11 | /// 12 | /// The source collection. 13 | /// Type of the collection items. 14 | /// HashSet containing of the collection items. 15 | /// If source is null. 16 | [PublicAPI, NotNull] public static HashSet ToHashSet(this IEnumerable source) => new HashSet(source); 17 | 18 | public static IEnumerable SelectWhere(this IEnumerable source, Func predicate) 19 | { 20 | foreach (TSource element in source) 21 | { 22 | (bool eligible, TResult result) = predicate(element); 23 | 24 | if (eligible) 25 | yield return result; 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Runtime/Extensions/EnumerableExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f4e726bd7eab4469b11fb6e3a19de6df 3 | timeCreated: 1604474309 -------------------------------------------------------------------------------- /Runtime/Extensions/FloatExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | 6 | /// 7 | /// Different useful extensions for . 8 | /// 9 | public static class FloatExtensions 10 | { 11 | /// Determines if the numbers are equal with a certain tolerance. 12 | /// First number. 13 | /// Second number. 14 | /// Tolerance by which to determine if the numbers are equal. Default is 0.01f. 15 | /// Whether the numbers are equal with tolerance. 16 | /// 17 | /// if (contentHeight.ApproximatelyEquals(position.height)) 18 | /// return true; 19 | /// 20 | [PublicAPI] public static bool ApproximatelyEquals(this float firstNum, float secondNum, float tolerance = 0.01f) 21 | { 22 | return Math.Abs(firstNum - secondNum) < tolerance; 23 | } 24 | 25 | /// Determines if the number are not equal with a certain tolerance. 26 | /// First number. 27 | /// Second number. 28 | /// Tolerance by which to determine if the numbers are equal. Default is 0.01f. 29 | /// Whether the numbers are not equal with tolerance. 30 | /// 31 | /// if (_optimalWidth.DoesNotEqualApproximately(position.width)) 32 | /// this.Resize(_optimalWidth); 33 | /// 34 | [PublicAPI] public static bool DoesNotEqualApproximately(this float firstNum, float secondNum, float tolerance = 0.01f) => 35 | !firstNum.ApproximatelyEquals(secondNum, tolerance); 36 | } 37 | } -------------------------------------------------------------------------------- /Runtime/Extensions/FloatExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9acda7d875264251a22c4bda13aeb242 3 | timeCreated: 1599675904 -------------------------------------------------------------------------------- /Runtime/Extensions/HashSetExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bf6db19dc7cc408d9afac7fa7d00b4d5 3 | timeCreated: 1604225883 -------------------------------------------------------------------------------- /Runtime/Extensions/MemberInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using System.Reflection; 5 | using JetBrains.Annotations; 6 | 7 | public static class MemberInfoExtensions 8 | { 9 | /// 10 | /// Checks whether the member has a custom attribute of type . 11 | /// 12 | /// The member to check. 13 | /// The type of attribute to search for. 14 | /// true if the type has a custom attribute of type . 15 | [PublicAPI, Pure] 16 | public static bool HasAttribute(this MemberInfo member) 17 | where T : Attribute 18 | { 19 | // GetCustomAttributes() skips a number of null checks and a pretty long method call chain. 20 | return member.GetCustomAttributes(typeof(T), true).Length != 0; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Runtime/Extensions/MemberInfoExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2ebcdd607c884de6982278f2406065be 3 | timeCreated: 1611659056 -------------------------------------------------------------------------------- /Runtime/Extensions/RectExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using JetBrains.Annotations; 4 | using UnityEngine; 5 | 6 | /// Different useful extensions for . 7 | public static class RectExtensions 8 | { 9 | /// Rounds up x, y, width, and height of the rect. 10 | /// Rect to round coordinates for. 11 | /// popupArea.RoundUpCoordinates(); 12 | [PublicAPI] public static void RoundUpCoordinates(this ref Rect rect) 13 | { 14 | rect.x = Mathf.Round(rect.x); 15 | rect.y = Mathf.Round(rect.y); 16 | rect.width = Mathf.Round(rect.width); 17 | rect.height = Mathf.Round(rect.height); 18 | } 19 | 20 | /// 21 | /// Cuts a big rect into two smaller ones by placing a vertical cut at from the 22 | /// left or right border of the rect. 23 | /// 24 | /// The rect that should be split. 25 | /// 26 | /// The distance from the left or right border of the rect where to place vertical cut. 27 | /// 28 | /// Whether to count the distance from left or right border. 29 | /// Left and right rects that appeared after the cut. 30 | /// 31 | /// (Rect searchFieldArea, Rect buttonArea) = innerToolbarArea.CutVertically(DropdownStyle.IconSize, true); 32 | /// 33 | [PublicAPI] public static (Rect leftRect, Rect rightRect) CutVertically(this Rect originalRect, float cutDistance, 34 | bool fromRightSide = false) 35 | { 36 | Rect leftRect, rightRect; 37 | 38 | Vector2 leftRectPos = originalRect.position; 39 | Vector2 RightRectPos() => new Vector2(originalRect.x + leftRect.width, originalRect.y); 40 | var cutDistanceSize = new Vector2(cutDistance, originalRect.height); 41 | var leftoverSize = new Vector2(originalRect.width - cutDistance, originalRect.height); 42 | 43 | if (fromRightSide) 44 | { 45 | leftRect = new Rect(leftRectPos, leftoverSize); 46 | rightRect = new Rect(RightRectPos(), cutDistanceSize); 47 | } 48 | else 49 | { 50 | leftRect = new Rect(leftRectPos, cutDistanceSize); 51 | rightRect = new Rect(RightRectPos(), leftoverSize); 52 | } 53 | 54 | return (leftRect, rightRect); 55 | } 56 | 57 | /// Creates padding to the left and right of a rectangle by narrowing it down. 58 | /// The bigger rect to create padding for. 59 | /// Width of the left padding in pixels. 60 | /// Width of the right padding in pixels. 61 | /// The smaller rect that appeared after creating paddings. 62 | /// Rect innerToolbarArea = outerToolbarArea.AddHorizontalPadding(10f, 2f); 63 | [PublicAPI] public static Rect AddHorizontalPadding(this Rect rect, float leftPadding, float rightPadding) 64 | { 65 | rect.xMin += leftPadding; 66 | rect.width -= rightPadding; 67 | return rect; 68 | } 69 | 70 | /// Places a rect with a smaller height vertically in the middle of a bigger rect. 71 | /// The bigger rect. 72 | /// The height of a smaller rect. 73 | /// 74 | /// The smaller rect with a given height that was aligned vertically in the middle of a bigger rect. 75 | /// 76 | /// 77 | /// Rect innerToolbarArea = outerToolbarArea.AlignMiddleVertically(DropdownStyle.LabelHeight); 78 | /// 79 | [PublicAPI] public static Rect AlignMiddleVertically(this Rect rect, float height) 80 | { 81 | rect.y = rect.y + rect.height * 0.5f - height * 0.5f; 82 | rect.height = height; 83 | return rect; 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /Runtime/Extensions/RectExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ddc18f0ed7b5440c8e43557d45e4dcc3 3 | timeCreated: 1597509376 -------------------------------------------------------------------------------- /Runtime/Extensions/RectLineIntersectionHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d4a1203a0f594a979f975f7802620a47 3 | timeCreated: 1624273401 -------------------------------------------------------------------------------- /Runtime/Extensions/RegexExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using System.Text.RegularExpressions; 5 | using JetBrains.Annotations; 6 | 7 | /// 8 | /// Different useful extension methods for . 9 | /// 10 | public static class RegexExtensions 11 | { 12 | /// 13 | /// Searches for a match in and returns it. If there is no match, throws . 14 | /// 15 | /// The regex to use for search. 16 | /// The text to search in. 17 | /// Match that was found in the . 18 | /// If no match was found in . 19 | [PublicAPI] 20 | public static string Find(this Regex regex, string text) 21 | { 22 | string result = regex.Match(text).Value; 23 | 24 | if (result.Length == 0) 25 | throw new ArgumentException($"Failed to find \"{regex}\" in the following text: \"{text}\"."); 26 | 27 | return result; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Runtime/Extensions/RegexExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 047b3c461ae444fe8f22bb0f9f57d38e 3 | timeCreated: 1606838363 -------------------------------------------------------------------------------- /Runtime/Extensions/SpanExtensions.cs: -------------------------------------------------------------------------------- 1 | #if COMPILERSERVICES_UNSAFE 2 | namespace SolidUtilities 3 | { 4 | using System; 5 | using System.Runtime.CompilerServices; 6 | using JetBrains.Annotations; 7 | 8 | // Reduced-down and slightly refactored version of https://gist.github.com/LordJZ/92b7decebe52178a445a0b82f63e585a 9 | // It exposes only (T separator) overload of the Split method which was enough for my needs. 10 | public static class SpanExtensions 11 | { 12 | public readonly ref struct Enumerable 13 | where T : IEquatable 14 | { 15 | private readonly ReadOnlySpan _span; 16 | private readonly T _separator; 17 | 18 | public Enumerable(ReadOnlySpan span, T separator) 19 | { 20 | _span = span; 21 | _separator = separator; 22 | } 23 | 24 | [PublicAPI] 25 | public Enumerator GetEnumerator() => new Enumerator(_span, _separator); 26 | } 27 | 28 | public ref struct Enumerator 29 | where T : IEquatable 30 | { 31 | private const int SeparatorLength = 1; 32 | private readonly ReadOnlySpan _trailingEmptyItemSentinel; 33 | 34 | private readonly T _separator; 35 | private ReadOnlySpan _span; 36 | private ReadOnlySpan _current; 37 | 38 | public Enumerator(ReadOnlySpan span, T separator) 39 | { 40 | _span = span; 41 | _separator = separator; 42 | _current = default; 43 | _trailingEmptyItemSentinel = Unsafe.As(nameof(_trailingEmptyItemSentinel)).AsSpan(); 44 | 45 | if (_span.IsEmpty) 46 | TrailingEmptyItem = true; 47 | } 48 | 49 | [PublicAPI] 50 | public ReadOnlySpan Current => _current; 51 | 52 | private bool TrailingEmptyItem 53 | { 54 | get => _span == _trailingEmptyItemSentinel; 55 | set => _span = value ? _trailingEmptyItemSentinel : default; 56 | } 57 | 58 | [PublicAPI] 59 | public bool MoveNext() 60 | { 61 | if (TrailingEmptyItem) 62 | { 63 | TrailingEmptyItem = false; 64 | _current = default; 65 | return true; 66 | } 67 | 68 | if (_span.IsEmpty) 69 | { 70 | _span = _current = default; 71 | return false; 72 | } 73 | 74 | int idx = _span.IndexOf(_separator); 75 | if (idx < 0) 76 | { 77 | _current = _span; 78 | _span = default; 79 | } 80 | else 81 | { 82 | _current = _span.Slice(0, idx); 83 | _span = _span.Slice(idx + SeparatorLength); 84 | if (_span.IsEmpty) 85 | TrailingEmptyItem = true; 86 | } 87 | 88 | return true; 89 | } 90 | } 91 | 92 | [Pure, PublicAPI] 93 | public static Enumerable Split(this ReadOnlySpan span, T separator) 94 | where T : IEquatable => new Enumerable(span, separator); 95 | } 96 | } 97 | #endif -------------------------------------------------------------------------------- /Runtime/Extensions/SpanExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 919878685e674c159d833250059a6c67 3 | timeCreated: 1610983551 -------------------------------------------------------------------------------- /Runtime/Extensions/StringExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e24522c01a414ca689127ef099e53669 3 | timeCreated: 1603362370 -------------------------------------------------------------------------------- /Runtime/Extensions/Texture2DExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using JetBrains.Annotations; 4 | using UnityEngine; 5 | 6 | /// Different useful extensions for . 7 | public static class Texture2DExtensions 8 | { 9 | /// Rotates the input texture by 90 degrees and returns the new rotated texture. 10 | /// Texture to rotate. 11 | /// Whether to rotate the texture clockwise. 12 | /// The rotated texture. 13 | /// EditorIcon TriangleDown = new EditorIcon(Database.TriangleRight.Rotate()); 14 | [PublicAPI] public static Texture2D Rotate(this Texture2D texture, bool clockwise = true) 15 | { 16 | var original = texture.GetPixels32(); 17 | var rotated = new Color32[original.Length]; 18 | int textureWidth = texture.width; 19 | int textureHeight = texture.height; 20 | int origLength = original.Length; 21 | 22 | for (int heightIndex = 0; heightIndex < textureHeight; ++heightIndex) 23 | { 24 | for (int widthIndex = 0; widthIndex < textureWidth; ++widthIndex) 25 | { 26 | int rotIndex = (widthIndex + 1) * textureHeight - heightIndex - 1; 27 | 28 | int origIndex = clockwise 29 | ? origLength - 1 - (heightIndex * textureWidth + widthIndex) 30 | : heightIndex * textureWidth + widthIndex; 31 | 32 | rotated[rotIndex] = original[origIndex]; 33 | } 34 | } 35 | 36 | var rotatedTexture = new Texture2D(textureHeight, textureWidth); 37 | rotatedTexture.SetPixels32(rotated); 38 | rotatedTexture.Apply(); 39 | return rotatedTexture; 40 | } 41 | 42 | /// Draws the texture in a given rect. 43 | /// The texture to draw. 44 | /// Rectangle in which to draw the texture. 45 | /// tintedIcon.Draw(triangleRect); 46 | [PublicAPI] public static void Draw(this Texture2D texture, Rect rect) => GUI.DrawTexture(rect, texture); 47 | } 48 | } -------------------------------------------------------------------------------- /Runtime/Extensions/Texture2DExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1bb002d51c034f90a9123093ca4cd0d9 3 | timeCreated: 1600420239 -------------------------------------------------------------------------------- /Runtime/Extensions/TypeExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: eaa29a1568c64ebdbdd280953c0a4fd3 3 | timeCreated: 1598989656 -------------------------------------------------------------------------------- /Runtime/Extensions/Vector2Extensions.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using UnityEngine; 6 | 7 | /// Different useful extensions for . 8 | public static class Vector2Extensions 9 | { 10 | /// Creates a smaller rect with the given size inside of a bigger rect. 11 | /// The width and height of a smaller rect. 12 | /// The bigger rect. 13 | /// A rect centered inside of . 14 | /// 15 | /// If x or y coordinates of are bigger than width or height 16 | /// of . 17 | /// 18 | [PublicAPI] public static Rect Center(this Vector2 smallerRectSize, Rect outerRect) 19 | { 20 | if (smallerRectSize.x > outerRect.width) 21 | { 22 | throw new ArgumentOutOfRangeException($"The x value of {nameof(smallerRectSize)} must be " + 23 | $"less or equal to {nameof(outerRect)}.width. Actual values " + 24 | $"were: {smallerRectSize.x} > {outerRect.width}."); 25 | } 26 | 27 | if (smallerRectSize.y > outerRect.height) 28 | { 29 | throw new ArgumentOutOfRangeException($"The y value of {nameof(smallerRectSize)} must be " + 30 | $"less or equal to {nameof(outerRect)}.height. Actual values " + 31 | $"were: {smallerRectSize.y} > {outerRect.height}."); 32 | } 33 | 34 | float horizontalPadding = (outerRect.width - smallerRectSize.x) / 2f; 35 | float verticalPadding = (outerRect.height - smallerRectSize.y) / 2f; 36 | var smallerRectPosition = new Vector2(outerRect.x + horizontalPadding, outerRect.y + verticalPadding); 37 | return new Rect(smallerRectPosition, smallerRectSize); 38 | } 39 | 40 | /// Returns a new vector with values rounded up to the nearest integers. 41 | /// The vector which values to round up. 42 | /// New vector with rounded values. 43 | [PublicAPI] 44 | public static Vector2 RoundUp(this Vector2 vector) 45 | { 46 | vector.x = Mathf.Round(vector.x); 47 | vector.y = Mathf.Round(vector.y); 48 | return vector; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Runtime/Extensions/Vector2Extensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ace5b22e608244b3b198762c4709c8e2 3 | timeCreated: 1602689417 -------------------------------------------------------------------------------- /Runtime/Helpers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cc9f4ad9420b4045965b351403f0620a 3 | timeCreated: 1602441364 -------------------------------------------------------------------------------- /Runtime/Helpers/ArrayEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System.Collections.Generic; 4 | using JetBrains.Annotations; 5 | 6 | /// 7 | /// Generic EqualityComparer for an array of that allows for quick equality check of arrays 8 | /// and enables using them as keys in collections (provides GetHashCode method). 9 | /// Note that elements of the array must correctly pass equality check for this (override ). 10 | /// 11 | /// The type of array elements. 12 | public class ArrayEqualityComparer : IEqualityComparer 13 | { 14 | private readonly EqualityComparer _elementComparer; 15 | 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// 20 | /// Custom element comparer. Uses by default. 21 | /// 22 | [PublicAPI] 23 | public ArrayEqualityComparer(EqualityComparer customElementComparer = null) 24 | { 25 | _elementComparer = customElementComparer ?? EqualityComparer.Default; 26 | } 27 | 28 | [PublicAPI] 29 | public bool Equals(T[] first, T[] second) 30 | { 31 | if (first == second) 32 | return true; 33 | 34 | if (first == null || second == null) 35 | return false; 36 | 37 | if (first.Length != second.Length) 38 | return false; 39 | 40 | for (int i = 0; i < first.Length; i++) 41 | { 42 | if ( ! _elementComparer.Equals(first[i], second[i])) 43 | { 44 | return false; 45 | } 46 | } 47 | 48 | return true; 49 | } 50 | 51 | [PublicAPI] 52 | public int GetHashCode(T[] array) 53 | { 54 | unchecked 55 | { 56 | int hash = 17; 57 | 58 | foreach (T element in array) 59 | { 60 | hash = hash * 31 + _elementComparer.GetHashCode(element); 61 | } 62 | 63 | return hash; 64 | } 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /Runtime/Helpers/ArrayEqualityComparer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 161f42def6bf46b3b13e3381734885b2 3 | timeCreated: 1608289657 -------------------------------------------------------------------------------- /Runtime/Helpers/ArrayHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | 5 | public static class ArrayHelper 6 | { 7 | public static void Add(ref T[] array, T item) 8 | { 9 | if (array == null) 10 | { 11 | array = new T[] { item }; 12 | return; 13 | } 14 | 15 | Array.Resize(ref array, array.Length + 1); 16 | array[array.Length - 1] = item; 17 | } 18 | 19 | public static void RemoveAt(ref T[] array, int index) 20 | { 21 | if (index < 0 || index >= array.Length) 22 | throw new ArgumentOutOfRangeException($"The passed index {index} is out of bounds of the array with length {array.Length}"); 23 | 24 | var newArray = new T[array.Length - 1]; 25 | 26 | int j = 0; 27 | for (int i = 0; i < array.Length; i++) 28 | { 29 | if (i == index) 30 | continue; 31 | 32 | newArray[j] = array[i]; 33 | j++; 34 | } 35 | 36 | array = newArray; 37 | } 38 | 39 | public static bool Remove(ref T[] array, T item) 40 | { 41 | int index = Array.IndexOf(array, item); 42 | 43 | if (index == -1) 44 | return false; 45 | 46 | RemoveAt(ref array, index); 47 | return true; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /Runtime/Helpers/ArrayHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0796890bcc004bf39b866cf7457945d2 3 | timeCreated: 1642798458 -------------------------------------------------------------------------------- /Runtime/Helpers/FastIterationDictionary.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7a37e77f542a43d5bc334aa8848a2e3d 3 | timeCreated: 1610636319 -------------------------------------------------------------------------------- /Runtime/Helpers/FuzzySearch.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 950ae3ef7899489c8a79a466d526b7c8 3 | timeCreated: 1600030284 -------------------------------------------------------------------------------- /Runtime/Helpers/GUIHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using UnityEngine; 6 | 7 | public static class GUIHelper 8 | { 9 | private static readonly GUIStyle _closeButtonStyle = GUI.skin.FindStyle("ToolbarSeachCancelButton"); 10 | 11 | /// Draws the close button. 12 | /// Rect the button should be located in. 13 | /// Whether the button was pressed. 14 | /// 15 | /// if (DrawHelper.CloseButton(buttonRect)) 16 | /// { 17 | /// searchText = string.Empty; 18 | /// GUI.FocusControl(null); 19 | /// } 20 | /// 21 | [PublicAPI] public static bool CloseButton(Rect buttonRect) 22 | { 23 | // This is a known problem that the button does not align to center horizontally for some reason. 24 | // I tried alignment = TextAnchor.MiddleCenter, setting padding and margin to different values, 25 | // but to no avail. Any help with this is appreciated. 26 | return GUI.Button(buttonRect, GUIContent.none, _closeButtonStyle); 27 | } 28 | 29 | /// 30 | /// Draws content in scroll view. 31 | /// 32 | /// Rectangle on the screen to use for the ScrollView. 33 | /// The pixel distance that the view is scrolled in the X and Y directions. 34 | /// The rectangle used inside the scrollView. 35 | public static ScrollView ScrollViewBlock(Rect position, ref Vector2 scrollPosition, Rect viewRect) => new ScrollView(position, ref scrollPosition, viewRect); 36 | 37 | public readonly struct ScrollView : IDisposable 38 | { 39 | public ScrollView(Rect position, ref Vector2 scrollPosition, Rect viewRect) 40 | { 41 | scrollPosition = GUI.BeginScrollView(position, scrollPosition, viewRect); 42 | } 43 | 44 | public void Dispose() => GUI.EndScrollView(); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/Helpers/GUIHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 687c6cb0910b41fc839ecfde4a2389ca 3 | timeCreated: 1626540257 -------------------------------------------------------------------------------- /Runtime/Helpers/GUILayoutAreaBlock.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using UnityEngine; 5 | 6 | 7 | } -------------------------------------------------------------------------------- /Runtime/Helpers/GUILayoutAreaBlock.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 662bde7ba3b04127867ccf42b08115e8 3 | timeCreated: 1626538532 -------------------------------------------------------------------------------- /Runtime/Helpers/GUILayoutHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using JetBrains.Annotations; 5 | using UnityEngine; 6 | 7 | public static class GUILayoutHelper 8 | { 9 | private static readonly GUILayoutOption _expandWidthTrue = GUILayout.ExpandWidth(true); 10 | private static readonly GUILayoutOption _expandWidthFalse = GUILayout.ExpandWidth(true); 11 | 12 | /// 13 | /// Draws content in the horizontal direction. 14 | /// 15 | /// The style to draw with. 16 | public static Horizontal HorizontalBlock(GUIStyle style = null) => new Horizontal(style); 17 | 18 | public readonly struct Horizontal : IDisposable 19 | { 20 | public Horizontal([CanBeNull] GUIStyle style) 21 | { 22 | if (style == null) 23 | { 24 | GUILayout.BeginHorizontal((GUILayoutOption[]) null); 25 | } 26 | else 27 | { 28 | GUILayout.BeginHorizontal(style, null); 29 | } 30 | } 31 | 32 | public void Dispose() => GUILayout.EndHorizontal(); 33 | } 34 | 35 | /// 36 | /// Draws content in the vertical direction. 37 | /// 38 | /// The style to draw with. 39 | public static Vertical VerticalBlock(GUIStyle style = null) => new Vertical(style); 40 | 41 | [PublicAPI] 42 | public readonly struct Vertical : IDisposable 43 | { 44 | public Vertical([CanBeNull] GUIStyle style) 45 | { 46 | if (style == null) 47 | { 48 | GUILayout.BeginVertical(Array.Empty()); 49 | } 50 | else 51 | { 52 | GUILayout.BeginVertical(style, null); 53 | } 54 | } 55 | 56 | public void Dispose() => GUILayout.EndHorizontal(); 57 | } 58 | 59 | /// 60 | /// Draws content in GUILayout area. 61 | /// 62 | /// Screen rect to draw the content in. 63 | public static Area AreaBlock(Rect screenRect) => new Area(screenRect); 64 | 65 | public readonly struct Area : IDisposable 66 | { 67 | public Area(Rect screenRect) 68 | { 69 | GUILayout.BeginArea(screenRect); 70 | } 71 | 72 | public void Dispose() => GUILayout.EndArea(); 73 | } 74 | 75 | /// 76 | /// that is instantiated only once, reducing the garbage collection overhead. 77 | /// 78 | /// Whether to expand width. 79 | /// with the given expand bool. 80 | /// 81 | /// EditorGUILayout.BeginHorizontal( 82 | /// SearchToolbarStyle, 83 | /// GUILayout.Height(toolbarHeight), 84 | /// DrawHelper.ExpandWidth(false)); 85 | /// 86 | [PublicAPI] public static GUILayoutOption ExpandWidth(bool expand) => expand ? _expandWidthTrue : _expandWidthFalse; 87 | } 88 | } -------------------------------------------------------------------------------- /Runtime/Helpers/GUILayoutHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 982101706d814c01ad280ed04228c2bd 3 | timeCreated: 1626540261 -------------------------------------------------------------------------------- /Runtime/Helpers/Hash.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System.Security.Cryptography; 4 | using System.Text; 5 | using JetBrains.Annotations; 6 | 7 | /// Collection of useful hashing methods. 8 | [PublicAPI] 9 | public static class Hash 10 | { 11 | /// 12 | /// Hashes using and converts bytes array to string. 13 | /// 14 | /// The string to hash. 15 | /// SHA1 hash converted to string. 16 | /// If is null. 17 | [NotNull] 18 | public static string SHA1(string input) 19 | { 20 | var plaintextBytes = Encoding.UTF8.GetBytes(input); 21 | 22 | byte[] hashBytes; 23 | 24 | using (var sha1 = new SHA1Managed()) 25 | hashBytes = sha1.ComputeHash(plaintextBytes); 26 | 27 | var sb = new StringBuilder(); 28 | 29 | foreach (byte hashByte in hashBytes) 30 | sb.AppendFormat("{0:x2}", hashByte); 31 | 32 | return sb.ToString(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Runtime/Helpers/Hash.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7864001fe6a040f3a7d5fca75f00f61e 3 | timeCreated: 1603797690 -------------------------------------------------------------------------------- /Runtime/Helpers/ListHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System.Collections.Generic; 4 | 5 | public static class ListHelper 6 | { 7 | public static List Empty() 8 | { 9 | return EmptyList.Value; 10 | } 11 | 12 | private static class EmptyList 13 | { 14 | public static readonly List Value = new List(0); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Runtime/Helpers/ListHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8874854617b04f019b174b7d400432c2 3 | timeCreated: 1629055957 -------------------------------------------------------------------------------- /Runtime/Helpers/PathHelper.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text.RegularExpressions; 7 | using JetBrains.Annotations; 8 | 9 | public static class PathHelper 10 | { 11 | /// 12 | /// Rebases file with path fromPath to folder with baseDir. 13 | /// 14 | /// Full file path (absolute). 15 | /// Full base directory path (absolute). 16 | /// Relative path to file in respect of baseDir. 17 | [PublicAPI] 18 | public static string MakeRelative(string fromPath, string baseDir) 19 | { 20 | const string pathSep = "\\"; 21 | string fullFromPath = Path.GetFullPath(fromPath); 22 | // If folder contains upper folder references, they gets lost here. "c:\test\..\test2" => "c:\test2" 23 | string fullBaseDir = Path.GetFullPath(baseDir); 24 | 25 | string[] p1 = Regex.Split(fullFromPath, "[\\\\/]").Where(x => x.Length != 0).ToArray(); 26 | string[] p2 = Regex.Split(fullBaseDir, "[\\\\/]").Where(x => x.Length != 0).ToArray(); 27 | int i = 0; 28 | 29 | for (; i < p1.Length && i < p2.Length; i++) 30 | { 31 | if (string.Compare(p1[i], p2[i], StringComparison.OrdinalIgnoreCase) != 0) 32 | break; 33 | } 34 | 35 | // Cannot make relative path, for example if resides on different drive 36 | if (i == 0) 37 | return fullFromPath; 38 | 39 | string r = string.Join(pathSep, Enumerable.Repeat("..", p2.Length - i).Concat(p1.Skip(i).Take(p1.Length - i))); 40 | return r; 41 | } 42 | 43 | /// 44 | /// Returns true if starts with the path . 45 | /// The comparison is case-insensitive, handles / and \ slashes as folder separators and 46 | /// only matches if the base dir folder name is matched exactly ("c:\foobar\file.txt" is not a sub path of "c:\foo"). 47 | /// 48 | [PublicAPI] 49 | public static bool IsSubPathOf(string path, string baseDirPath) 50 | { 51 | string normalizedPath = Path.GetFullPath(path.Replace('/', '\\').WithEnding("\\")); 52 | string normalizedBaseDirPath = Path.GetFullPath(baseDirPath.Replace('/', '\\').WithEnding("\\")); 53 | return normalizedPath.StartsWith(normalizedBaseDirPath, StringComparison.OrdinalIgnoreCase); 54 | } 55 | 56 | /// 57 | /// Returns with the minimal concatenation of (starting from end) that 58 | /// results in satisfying .EndsWith(ending). 59 | /// 60 | /// "hel".WithEnding("llo") returns "hello", which is the result of "hel" + "lo". 61 | private static string WithEnding([CanBeNull] this string str, string ending) 62 | { 63 | if (str == null) 64 | return ending; 65 | 66 | string result = str; 67 | 68 | // Right() is 1-indexed, so include these cases 69 | // * Append no characters 70 | // * Append up to N characters, where N is ending length 71 | for (int i = 0; i <= ending.Length; i++) 72 | { 73 | string tmp = result + ending.GetEnding(i); 74 | if (tmp.EndsWith(ending)) 75 | return tmp; 76 | } 77 | 78 | return result; 79 | } 80 | 81 | /// Gets the rightmost characters from a string. 82 | /// The string to retrieve the substring from. 83 | /// The number of characters to retrieve. 84 | /// The substring. 85 | private static string GetEnding([NotNull] this string value, int length) 86 | { 87 | if (value == null) 88 | { 89 | throw new ArgumentNullException(nameof(value)); 90 | } 91 | 92 | if (length < 0) 93 | { 94 | throw new ArgumentOutOfRangeException(nameof(length), length, "Length is less than zero"); 95 | } 96 | 97 | return (length < value.Length) ? value.Substring(value.Length - length) : value; 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /Runtime/Helpers/PathHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a29a5a5c04b5467a87c51d210131cd8e 3 | timeCreated: 1623497741 -------------------------------------------------------------------------------- /Runtime/Helpers/Timer.cs: -------------------------------------------------------------------------------- 1 | namespace SolidUtilities 2 | { 3 | using System; 4 | using System.Diagnostics; 5 | using JetBrains.Annotations; 6 | using Debug = UnityEngine.Debug; 7 | 8 | /// 9 | /// Basic timer that logs execution time of a method or part of the method. It does not warm up the execution and 10 | /// runs the actions only once. 11 | /// 12 | [PublicAPI] 13 | public readonly struct Timer : IDisposable 14 | { 15 | private readonly TimeUnit _timeUnit; 16 | private readonly Stopwatch _stopwatch; 17 | private readonly string _actionName; 18 | private readonly int _iterationCount; 19 | 20 | private Timer(string actionName, TimeUnit timeUnit, int iterationCount) 21 | { 22 | _timeUnit = timeUnit; 23 | _stopwatch = Stopwatch.StartNew(); 24 | _actionName = actionName; 25 | _iterationCount = iterationCount; 26 | } 27 | 28 | private enum TimeUnit { Milliseconds, Nanoseconds } 29 | 30 | /// Log time the action took in milliseconds. 31 | /// Name of the action which execution is measured. 32 | /// Number of iterations an action is run inside the timer. Defaults to 1. 33 | /// New instance of timer. 34 | /// 35 | /// using (Timer.CheckInMilliseconds("Show popup")) 36 | /// { 37 | /// var dropdownWindow = new DropdownWindow(rect); 38 | /// dropdownWindow.ShowInPopup(); 39 | /// } 40 | /// 41 | public static Timer CheckInMilliseconds(string actionName, int iterationCount = 1) 42 | { 43 | return new Timer(actionName, TimeUnit.Milliseconds, iterationCount); 44 | } 45 | 46 | /// Log time the action took in nanoseconds. 47 | /// Name of the action which execution is measured. 48 | /// Number of iterations an action is run inside the timer. Defaults to 1. 49 | /// New instance of timer. 50 | /// 51 | /// using (Timer.CheckInNanoseconds("Show popup")) 52 | /// { 53 | /// var dropdownWindow = new DropdownWindow(rect); 54 | /// dropdownWindow.ShowInPopup(); 55 | /// } 56 | /// 57 | public static Timer CheckInNanoseconds(string actionName, int iterationCount = 1) 58 | { 59 | return new Timer(actionName, TimeUnit.Nanoseconds, iterationCount); 60 | } 61 | 62 | public void Dispose() 63 | { 64 | _stopwatch.Stop(); 65 | int totalTime = GetTotalTime(); 66 | string unitName = GetUnitName(); 67 | 68 | string message = $"{_actionName} took {totalTime} {unitName}."; 69 | 70 | if (_iterationCount > 1) 71 | message += $" One iteration took {GetIterationTime(totalTime)} {unitName} on average."; 72 | 73 | Debug.Log(message); 74 | } 75 | 76 | private int GetTotalTime() 77 | { 78 | const int nanosecondsInAMillisecond = 1000000; 79 | 80 | switch (_timeUnit) 81 | { 82 | case TimeUnit.Milliseconds: 83 | return Convert.ToInt32(_stopwatch.ElapsedMilliseconds); 84 | case TimeUnit.Nanoseconds: 85 | return Convert.ToInt32(_stopwatch.Elapsed.TotalMilliseconds * nanosecondsInAMillisecond); 86 | } 87 | 88 | throw new NotImplementedException(); 89 | } 90 | 91 | private int GetIterationTime(int totalTime) => totalTime / _iterationCount; 92 | 93 | private string GetUnitName() 94 | { 95 | switch (_timeUnit) 96 | { 97 | case TimeUnit.Milliseconds: 98 | return "ms"; 99 | case TimeUnit.Nanoseconds: 100 | return "ns"; 101 | } 102 | 103 | throw new NotImplementedException(); 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /Runtime/Helpers/Timer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a796e73b5f904adeb8d8f5c2f15db907 3 | timeCreated: 1599324644 -------------------------------------------------------------------------------- /Runtime/Helpers/TypeHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1df48f1b9fc44d2f8f8179a28fc78647 3 | timeCreated: 1602441346 -------------------------------------------------------------------------------- /Runtime/SerializableCollections.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e78c15b1270665a4d9381b52997b92b8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/SerializableCollections/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mathieu Le Ber 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Runtime/SerializableCollections/LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b30cf31157501e54db6aaa88903fd890 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/SerializableCollections/SerializableDictionary.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e7be1c9624387604fba4005ccf7dbd5b 3 | timeCreated: 1492868176 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Runtime/SolidUtilities.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SolidUtilities", 3 | "rootNamespace": "SolidUtilities", 4 | "references": [], 5 | "includePlatforms": [], 6 | "excludePlatforms": [], 7 | "allowUnsafeCode": true, 8 | "overrideReferences": false, 9 | "precompiledReferences": [], 10 | "autoReferenced": true, 11 | "defineConstraints": [], 12 | "versionDefines": [ 13 | { 14 | "name": "org.nuget.system.runtime.compilerservices.unsafe", 15 | "expression": "", 16 | "define": "COMPILERSERVICES_UNSAFE" 17 | } 18 | ], 19 | "noEngineReferences": false 20 | } -------------------------------------------------------------------------------- /Runtime/SolidUtilities.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b73ef07971851e14fa74ae50b76f8225 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /UnityEditorInternals.Android.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SolidAlloy/SolidUtilities/71ceb90f6a772d5a74a9357d5f1a801e6b0bea8f/UnityEditorInternals.Android.dll -------------------------------------------------------------------------------- /UnityEditorInternals.Android.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 01d43d90304f9ae44a6b56e466992d33 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: 9 | - UNITY_ANDROID 10 | isPreloaded: 0 11 | isOverridable: 1 12 | isExplicitlyReferenced: 1 13 | validateReferences: 0 14 | platformData: 15 | - first: 16 | : Any 17 | second: 18 | enabled: 0 19 | settings: 20 | Exclude Android: 1 21 | Exclude Editor: 0 22 | Exclude Linux64: 1 23 | Exclude OSXUniversal: 1 24 | Exclude Win: 1 25 | Exclude Win64: 1 26 | - first: 27 | Android: Android 28 | second: 29 | enabled: 0 30 | settings: 31 | CPU: ARMv7 32 | - first: 33 | Any: 34 | second: 35 | enabled: 0 36 | settings: {} 37 | - first: 38 | Editor: Editor 39 | second: 40 | enabled: 1 41 | settings: 42 | CPU: AnyCPU 43 | DefaultValueInitialized: true 44 | OS: AnyOS 45 | - first: 46 | Standalone: Linux64 47 | second: 48 | enabled: 0 49 | settings: 50 | CPU: None 51 | - first: 52 | Standalone: OSXUniversal 53 | second: 54 | enabled: 0 55 | settings: 56 | CPU: None 57 | - first: 58 | Standalone: Win 59 | second: 60 | enabled: 0 61 | settings: 62 | CPU: None 63 | - first: 64 | Standalone: Win64 65 | second: 66 | enabled: 0 67 | settings: 68 | CPU: None 69 | - first: 70 | Windows Store Apps: WindowsStoreApps 71 | second: 72 | enabled: 0 73 | settings: 74 | CPU: AnyCPU 75 | userData: 76 | assetBundleName: 77 | assetBundleVariant: 78 | -------------------------------------------------------------------------------- /UnityEditorInternals.Ios.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SolidAlloy/SolidUtilities/71ceb90f6a772d5a74a9357d5f1a801e6b0bea8f/UnityEditorInternals.Ios.dll -------------------------------------------------------------------------------- /UnityEditorInternals.Ios.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2791d3fa50b57e447abf84446ce63633 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: 9 | - UNITY_IOS 10 | isPreloaded: 0 11 | isOverridable: 1 12 | isExplicitlyReferenced: 1 13 | validateReferences: 0 14 | platformData: 15 | - first: 16 | : Any 17 | second: 18 | enabled: 0 19 | settings: 20 | Exclude Android: 1 21 | Exclude Editor: 0 22 | Exclude Linux64: 1 23 | Exclude OSXUniversal: 1 24 | Exclude Win: 1 25 | Exclude Win64: 1 26 | - first: 27 | Android: Android 28 | second: 29 | enabled: 0 30 | settings: 31 | CPU: ARMv7 32 | - first: 33 | Any: 34 | second: 35 | enabled: 0 36 | settings: {} 37 | - first: 38 | Editor: Editor 39 | second: 40 | enabled: 1 41 | settings: 42 | CPU: AnyCPU 43 | DefaultValueInitialized: true 44 | OS: AnyOS 45 | - first: 46 | Standalone: Linux64 47 | second: 48 | enabled: 0 49 | settings: 50 | CPU: None 51 | - first: 52 | Standalone: OSXUniversal 53 | second: 54 | enabled: 0 55 | settings: 56 | CPU: None 57 | - first: 58 | Standalone: Win 59 | second: 60 | enabled: 0 61 | settings: 62 | CPU: None 63 | - first: 64 | Standalone: Win64 65 | second: 66 | enabled: 0 67 | settings: 68 | CPU: None 69 | - first: 70 | Windows Store Apps: WindowsStoreApps 71 | second: 72 | enabled: 0 73 | settings: 74 | CPU: AnyCPU 75 | userData: 76 | assetBundleName: 77 | assetBundleVariant: 78 | -------------------------------------------------------------------------------- /UnityEditorInternals.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SolidAlloy/SolidUtilities/71ceb90f6a772d5a74a9357d5f1a801e6b0bea8f/UnityEditorInternals.dll -------------------------------------------------------------------------------- /UnityEditorInternals.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d338be02a4ce27042b328e8d492d57ac 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: 9 | - UNITY_2020_1_OR_NEWER 10 | isPreloaded: 0 11 | isOverridable: 1 12 | isExplicitlyReferenced: 0 13 | validateReferences: 1 14 | platformData: 15 | - first: 16 | : Any 17 | second: 18 | enabled: 0 19 | settings: 20 | Exclude Editor: 0 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude Win: 1 24 | Exclude Win64: 1 25 | - first: 26 | Any: 27 | second: 28 | enabled: 0 29 | settings: {} 30 | - first: 31 | Editor: Editor 32 | second: 33 | enabled: 1 34 | settings: 35 | CPU: AnyCPU 36 | DefaultValueInitialized: true 37 | OS: AnyOS 38 | - first: 39 | Standalone: Linux64 40 | second: 41 | enabled: 0 42 | settings: 43 | CPU: None 44 | - first: 45 | Standalone: OSXUniversal 46 | second: 47 | enabled: 0 48 | settings: 49 | CPU: None 50 | - first: 51 | Standalone: Win 52 | second: 53 | enabled: 0 54 | settings: 55 | CPU: None 56 | - first: 57 | Standalone: Win64 58 | second: 59 | enabled: 0 60 | settings: 61 | CPU: None 62 | - first: 63 | Windows Store Apps: WindowsStoreApps 64 | second: 65 | enabled: 0 66 | settings: 67 | CPU: AnyCPU 68 | userData: 69 | assetBundleName: 70 | assetBundleVariant: 71 | -------------------------------------------------------------------------------- /UnityEditorInternals2019.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SolidAlloy/SolidUtilities/71ceb90f6a772d5a74a9357d5f1a801e6b0bea8f/UnityEditorInternals2019.dll -------------------------------------------------------------------------------- /UnityEditorInternals2019.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9643eb5cb2342314183eebb4e22b2db6 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: 9 | - UNITY_2019 10 | isPreloaded: 0 11 | isOverridable: 1 12 | isExplicitlyReferenced: 0 13 | validateReferences: 1 14 | platformData: 15 | - first: 16 | : Any 17 | second: 18 | enabled: 0 19 | settings: 20 | Exclude Editor: 0 21 | Exclude Linux64: 1 22 | Exclude OSXUniversal: 1 23 | Exclude Win: 1 24 | Exclude Win64: 1 25 | - first: 26 | Any: 27 | second: 28 | enabled: 0 29 | settings: {} 30 | - first: 31 | Editor: Editor 32 | second: 33 | enabled: 1 34 | settings: 35 | CPU: AnyCPU 36 | DefaultValueInitialized: true 37 | OS: AnyOS 38 | - first: 39 | Standalone: Linux64 40 | second: 41 | enabled: 0 42 | settings: 43 | CPU: None 44 | - first: 45 | Standalone: OSXUniversal 46 | second: 47 | enabled: 0 48 | settings: 49 | CPU: None 50 | - first: 51 | Standalone: Win 52 | second: 53 | enabled: 0 54 | settings: 55 | CPU: None 56 | - first: 57 | Standalone: Win64 58 | second: 59 | enabled: 0 60 | settings: 61 | CPU: None 62 | - first: 63 | Windows Store Apps: WindowsStoreApps 64 | second: 65 | enabled: 0 66 | settings: 67 | CPU: AnyCPU 68 | userData: 69 | assetBundleName: 70 | assetBundleVariant: 71 | -------------------------------------------------------------------------------- /UnityEngineInternals.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SolidAlloy/SolidUtilities/71ceb90f6a772d5a74a9357d5f1a801e6b0bea8f/UnityEngineInternals.dll -------------------------------------------------------------------------------- /UnityEngineInternals.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9e30566a3ced70a41963dc664e9ca1f5 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 1 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | : Any 16 | second: 17 | enabled: 0 18 | settings: 19 | Exclude Editor: 0 20 | Exclude Linux64: 0 21 | Exclude OSXUniversal: 0 22 | Exclude Win: 0 23 | Exclude Win64: 0 24 | - first: 25 | Any: 26 | second: 27 | enabled: 1 28 | settings: {} 29 | - first: 30 | Editor: Editor 31 | second: 32 | enabled: 1 33 | settings: 34 | CPU: AnyCPU 35 | DefaultValueInitialized: true 36 | OS: AnyOS 37 | - first: 38 | Standalone: Linux64 39 | second: 40 | enabled: 1 41 | settings: 42 | CPU: AnyCPU 43 | - first: 44 | Standalone: OSXUniversal 45 | second: 46 | enabled: 1 47 | settings: 48 | CPU: AnyCPU 49 | - first: 50 | Standalone: Win 51 | second: 52 | enabled: 1 53 | settings: 54 | CPU: x86 55 | - first: 56 | Standalone: Win64 57 | second: 58 | enabled: 1 59 | settings: 60 | CPU: x86_64 61 | - first: 62 | Windows Store Apps: WindowsStoreApps 63 | second: 64 | enabled: 0 65 | settings: 66 | CPU: AnyCPU 67 | userData: 68 | assetBundleName: 69 | assetBundleVariant: 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.solidalloy.util", 3 | "version": "1.40.0", 4 | "displayName": "Solid Utilities", 5 | "description": "Different utilities that simplify development in Unity3D", 6 | "keywords": [ 7 | "util", 8 | "utilities", 9 | "helper" 10 | ], 11 | "author": { 12 | "name": "SolidAlloy", 13 | "url": "https://github.com/SolidAlloy/" 14 | }, 15 | "type": "tool" 16 | } 17 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 64c02b76107cdf843bc340d455dd8bb8 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------