├── .github └── FUNDING.yml ├── Attributes.meta ├── Attributes ├── AttributeBase.cs ├── AttributeBase.cs.meta ├── AttributeBaseDrawer.cs ├── AttributeBaseDrawer.cs.meta ├── AutoPropertyAttribute.cs ├── AutoPropertyAttribute.cs.meta ├── ButtonMethodAttribute.cs ├── ButtonMethodAttribute.cs.meta ├── CharactersRangeAttribute.cs ├── CharactersRangeAttribute.cs.meta ├── ConditionalFieldAttribute.cs ├── ConditionalFieldAttribute.cs.meta ├── ConstantsSelectionAttribute.cs ├── ConstantsSelectionAttribute.cs.meta ├── DefinedValuesAttribute.cs ├── DefinedValuesAttribute.cs.meta ├── DisplayInspectorAttribute.cs ├── DisplayInspectorAttribute.cs.meta ├── DisplayPreviewAttribute.cs ├── DisplayPreviewAttribute.cs.meta ├── FoldoutAttribute.cs ├── FoldoutAttribute.cs.meta ├── InitializationFieldAttribute.cs ├── InitializationFieldAttribute.cs.meta ├── LayerAttribute.cs ├── LayerAttribute.cs.meta ├── MaxValueAttribute.cs ├── MaxValueAttribute.cs.meta ├── MinMaxRangeAttribute.cs ├── MinMaxRangeAttribute.cs.meta ├── MinValueAttribute.cs ├── MinValueAttribute.cs.meta ├── MustBeAssignedAttribute.cs ├── MustBeAssignedAttribute.cs.meta ├── MustBeAssignedConditionalFieldExclude.cs ├── MustBeAssignedConditionalFieldExclude.cs.meta ├── OverrideLabelAttribute.cs ├── OverrideLabelAttribute.cs.meta ├── PositiveValueOnlyAttribute.cs ├── PositiveValueOnlyAttribute.cs.meta ├── RangeVectorAttribute.cs ├── RangeVectorAttribute.cs.meta ├── ReadOnlyAttribute.cs ├── ReadOnlyAttribute.cs.meta ├── RegexStringAttribute.cs ├── RegexStringAttribute.cs.meta ├── RequireLayerAttribute.cs ├── RequireLayerAttribute.cs.meta ├── RequireLayerOtRagAttributeHandler.cs ├── RequireLayerOtRagAttributeHandler.cs.meta ├── RequireTagAttribute.cs ├── RequireTagAttribute.cs.meta ├── SceneAttribute.cs ├── SceneAttribute.cs.meta ├── SearchableEnumAttribute.cs ├── SearchableEnumAttribute.cs.meta ├── SeparatorAttribute.cs ├── SeparatorAttribute.cs.meta ├── SpriteLayerAttribute.cs ├── SpriteLayerAttribute.cs.meta ├── TagAttribute.cs ├── TagAttribute.cs.meta ├── TopmostComponentAttribute.cs └── TopmostComponentAttribute.cs.meta ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── Extensions.meta ├── Extensions ├── EditorExtensions.meta ├── EditorExtensions │ ├── MyDefinesUtility.cs │ ├── MyDefinesUtility.cs.meta │ ├── MyEditor.cs │ ├── MyEditor.cs.meta │ ├── MyEditorAudio.cs │ ├── MyEditorAudio.cs.meta │ ├── MyGUI.cs │ ├── MyGUI.cs.meta │ ├── MyHandles.cs │ ├── MyHandles.cs.meta │ ├── MyIconPresets.cs │ ├── MyIconPresets.cs.meta │ ├── MyScriptableObject.cs │ ├── MyScriptableObject.cs.meta │ ├── MySerializedProperty.cs │ └── MySerializedProperty.cs.meta ├── MyAlgorithms.cs ├── MyAlgorithms.cs.meta ├── MyCollections.cs ├── MyCollections.cs.meta ├── MyColor.cs ├── MyColor.cs.meta ├── MyCommonConstants.cs ├── MyCommonConstants.cs.meta ├── MyComponentUtility.cs ├── MyComponentUtility.cs.meta ├── MyCoroutines.cs ├── MyCoroutines.cs.meta ├── MyDebug.cs ├── MyDebug.cs.meta ├── MyDelayedActions.cs ├── MyDelayedActions.cs.meta ├── MyExtensions.cs ├── MyExtensions.cs.meta ├── MyGizmos.cs ├── MyGizmos.cs.meta ├── MyInput.cs ├── MyInput.cs.meta ├── MyLayers.cs ├── MyLayers.cs.meta ├── MyMath.cs ├── MyMath.cs.meta ├── MyNavMesh.cs ├── MyNavMesh.cs.meta ├── MyObsoleteExtensions.cs ├── MyObsoleteExtensions.cs.meta ├── MyPhysics.cs ├── MyPhysics.cs.meta ├── MyPhysicsExtensions.cs ├── MyPhysicsExtensions.cs.meta ├── MyQuaternionExtensions.cs ├── MyQuaternionExtensions.cs.meta ├── MyReflection.cs ├── MyReflection.cs.meta ├── MyRegex.cs ├── MyRegex.cs.meta ├── MyString.cs ├── MyString.cs.meta ├── MyTexture.cs ├── MyTexture.cs.meta ├── MyUI.cs ├── MyUI.cs.meta ├── MyUnityEventExtensions.cs ├── MyUnityEventExtensions.cs.meta ├── MyVectors.cs ├── MyVectors.cs.meta ├── TransformShakeExtension.cs └── TransformShakeExtension.cs.meta ├── LICENSE.md ├── LICENSE.md.meta ├── MyBox.asmdef ├── MyBox.asmdef.meta ├── README.md ├── README.md.meta ├── TODO.md ├── TODO.md.meta ├── Tools.meta ├── Tools ├── AssetPresetPreprocessor.meta ├── AssetPresetPreprocessor │ ├── AssetPresetPreprocessor.cs │ ├── AssetPresetPreprocessor.cs.meta │ ├── AssetsPresetPreprocessBase.cs │ ├── AssetsPresetPreprocessBase.cs.meta │ ├── AssetsPresetPreprocessEditor.cs │ └── AssetsPresetPreprocessEditor.cs.meta ├── Features.meta ├── Features │ ├── AutoSaveFeature.cs │ ├── AutoSaveFeature.cs.meta │ ├── CleanEmptyDirectoriesFeature.cs │ ├── CleanEmptyDirectoriesFeature.cs.meta │ ├── CollapsableEventDrawer.cs │ ├── CollapsableEventDrawer.cs.meta │ ├── IPrepareFeature.cs │ ├── IPrepareFeature.cs.meta │ ├── MoveComponentInInspectorMenuItems.cs │ ├── MoveComponentInInspectorMenuItems.cs.meta │ ├── SceneViewBookmarkHotkeys.cs │ ├── SceneViewBookmarkHotkeys.cs.meta │ ├── SelectionHistoryHotkeys.cs │ ├── SelectionHistoryHotkeys.cs.meta │ ├── ToggleInspectorDebugHotkey.cs │ ├── ToggleInspectorDebugHotkey.cs.meta │ ├── ToggleInspectorLockHotkey.cs │ └── ToggleInspectorLockHotkey.cs.meta ├── ImageStringConverter.meta ├── ImageStringConverter │ ├── ImageStringConverter.cs │ ├── ImageStringConverter.cs.meta │ ├── ImageToStringConverterEditor.cs │ └── ImageToStringConverterEditor.cs.meta ├── Internal.meta ├── Internal │ ├── ConditionalData.cs │ ├── ConditionalData.cs.meta │ ├── ConditionalUtility.cs │ ├── ConditionalUtility.cs.meta │ ├── CustomDrawerUtility.cs │ ├── CustomDrawerUtility.cs.meta │ ├── MyBoxInternalPath.cs │ ├── MyBoxInternalPath.cs.meta │ ├── MyBoxMenuItems.cs │ ├── MyBoxMenuItems.cs.meta │ ├── MyBoxSettings.cs │ ├── MyBoxSettings.cs.meta │ ├── MyBoxUtilities.cs │ ├── MyBoxUtilities.cs.meta │ ├── MyBoxVersion.cs │ ├── MyBoxVersion.cs.meta │ ├── MyBoxWindow.cs │ ├── MyBoxWindow.cs.meta │ ├── SearchablePopup.cs │ ├── SearchablePopup.cs.meta │ ├── UnityObjectEditor.cs │ └── UnityObjectEditor.cs.meta ├── MyEditorEvents.cs ├── MyEditorEvents.cs.meta ├── MyEditorEventsBehaviorHandler.cs ├── MyEditorEventsBehaviorHandler.cs.meta ├── MySceneBundle.cs ├── MySceneBundle.cs.meta ├── TimeTest.cs ├── TimeTest.cs.meta ├── Undone.meta ├── Undone │ ├── AnimationCreator.cs │ ├── AnimationCreator.cs.meta │ ├── EmbeddedAnimationCreator.cs │ ├── EmbeddedAnimationCreator.cs.meta │ ├── GLDraw.cs │ ├── GLDraw.cs.meta │ ├── MyLogger.cs │ ├── MyLogger.cs.meta │ ├── SerializedPropertyViewer.cs │ └── SerializedPropertyViewer.cs.meta ├── WarningsPool.cs └── WarningsPool.cs.meta ├── Types.meta ├── Types ├── AnimationStateReference.cs ├── AnimationStateReference.cs.meta ├── AssetFolderPath.cs ├── AssetFolderPath.cs.meta ├── AssetPath.cs ├── AssetPath.cs.meta ├── Billboard.cs ├── Billboard.cs.meta ├── CollectionWrapper.cs ├── CollectionWrapper.cs.meta ├── ColliderGizmo.cs ├── ColliderGizmo.cs.meta ├── ColliderToMesh.cs ├── ColliderToMesh.cs.meta ├── CommentaryComponent.cs ├── CommentaryComponent.cs.meta ├── CoroutineGroup.cs ├── CoroutineGroup.cs.meta ├── EditorTypes.meta ├── EditorTypes │ ├── ConditionallyColoredGUIBlock.cs │ ├── ConditionallyColoredGUIBlock.cs.meta │ ├── ConditionallyEnabledGUIBlock.cs │ ├── ConditionallyEnabledGUIBlock.cs.meta │ ├── DraggableHandler.cs │ ├── DraggableHandler.cs.meta │ ├── EditorPrefsBool.cs │ ├── EditorPrefsBool.cs.meta │ ├── EditorPrefsFloat.cs │ ├── EditorPrefsFloat.cs.meta │ ├── EditorPrefsInt.cs │ ├── EditorPrefsInt.cs.meta │ ├── EditorPrefsString.cs │ ├── EditorPrefsString.cs.meta │ ├── EditorPrefsType.cs │ ├── EditorPrefsType.cs.meta │ ├── EditorPrefsVector3.cs │ ├── EditorPrefsVector3.cs.meta │ ├── EditorWithSubEditors.cs │ ├── EditorWithSubEditors.cs.meta │ ├── IndentBlock.cs │ ├── IndentBlock.cs.meta │ ├── ReorderableCollection.cs │ ├── ReorderableCollection.cs.meta │ ├── SceneClickHandler.cs │ ├── SceneClickHandler.cs.meta │ ├── ScrollViewBlock.cs │ └── ScrollViewBlock.cs.meta ├── FPSCounter.cs ├── FPSCounter.cs.meta ├── GUID.meta ├── GUID │ ├── Credits.txt │ ├── Credits.txt.meta │ ├── GUIDEditor.meta │ ├── GUIDEditor │ │ ├── GuidComponentDrawer.cs │ │ ├── GuidComponentDrawer.cs.meta │ │ ├── GuidReferenceDrawer.cs │ │ └── GuidReferenceDrawer.cs.meta │ ├── GuidComponent.cs │ ├── GuidComponent.cs.meta │ ├── GuidManager.cs │ ├── GuidManager.cs.meta │ ├── GuidReference.cs │ └── GuidReference.cs.meta ├── MinMax.cs ├── MinMax.cs.meta ├── MyCursor.cs ├── MyCursor.cs.meta ├── MyDictionary.cs ├── MyDictionary.cs.meta ├── Optional.cs ├── Optional.cs.meta ├── OptionalMinMax.cs ├── OptionalMinMax.cs.meta ├── PlayerPrefsBool.cs ├── PlayerPrefsBool.cs.meta ├── PlayerPrefsFloat.cs ├── PlayerPrefsFloat.cs.meta ├── PlayerPrefsInt.cs ├── PlayerPrefsInt.cs.meta ├── PlayerPrefsString.cs ├── PlayerPrefsString.cs.meta ├── PlayerPrefsType.cs ├── PlayerPrefsType.cs.meta ├── PlayerPrefsVector2.cs ├── PlayerPrefsVector2.cs.meta ├── PlayerPrefsVector2Int.cs ├── PlayerPrefsVector2Int.cs.meta ├── PlayerPrefsVector3.cs ├── PlayerPrefsVector3.cs.meta ├── PlayerPrefsVector3Int.cs ├── PlayerPrefsVector3Int.cs.meta ├── Reorderable.cs ├── Reorderable.cs.meta ├── SceneReference.cs ├── SceneReference.cs.meta ├── Singleton.cs ├── Singleton.cs.meta ├── StateOnAwake.cs ├── StateOnAwake.cs.meta ├── TransformData.cs ├── TransformData.cs.meta ├── UIFollow.cs ├── UIFollow.cs.meta ├── UIImageBasedButton.cs ├── UIImageBasedButton.cs.meta ├── UIRelativePosition.cs ├── UIRelativePosition.cs.meta ├── UISizeBy.cs └── UISizeBy.cs.meta ├── package.json └── package.json.meta /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ["https://ko-fi.com/mybox"] 2 | -------------------------------------------------------------------------------- /Attributes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a64a1ca77606a0040b0b503f314f84e9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Attributes/AttributeBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace MyBox.Internal 5 | { 6 | [AttributeUsage(AttributeTargets.Field)] 7 | public abstract class AttributeBase : PropertyAttribute 8 | { 9 | #if UNITY_EDITOR 10 | /// 11 | /// Validation is called before all other methods. 12 | /// Once in OnGUI and once in GetPropertyHeight 13 | /// 14 | public virtual void ValidateProperty(UnityEditor.SerializedProperty property) 15 | { 16 | } 17 | 18 | 19 | public virtual void OnBeforeGUI(Rect position, UnityEditor.SerializedProperty property, GUIContent label) 20 | { 21 | } 22 | 23 | /// 24 | /// Called once per AttributeBase group. 25 | /// I.e. if something with higher order is drawn, later will be skipped 26 | /// 27 | /// false if nothing is drawn 28 | public virtual bool OnGUI(Rect position, UnityEditor.SerializedProperty property, GUIContent label) 29 | { 30 | return false; 31 | } 32 | 33 | public virtual void OnAfterGUI(Rect position, UnityEditor.SerializedProperty property, GUIContent label) 34 | { 35 | } 36 | 37 | /// 38 | /// Overriding occurs just like OnGUI. Once per group, attribute with higher priority first 39 | /// 40 | /// Null if not overriden 41 | public virtual float? OverrideHeight() 42 | { 43 | return null; 44 | } 45 | #endif 46 | } 47 | } -------------------------------------------------------------------------------- /Attributes/AttributeBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 816fc9d7c08c47f8b84318dce8cecf88 3 | timeCreated: 1582017264 -------------------------------------------------------------------------------- /Attributes/AttributeBaseDrawer.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System.Linq; 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | namespace MyBox.Internal 7 | { 8 | [CustomPropertyDrawer(typeof(AttributeBase), true)] 9 | public class AttributeBaseDrawer : PropertyDrawer 10 | { 11 | private AttributeBase[] _cachedAttributes; 12 | 13 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 14 | { 15 | CacheAttributes(); 16 | 17 | for (var i = _cachedAttributes.Length - 1; i >= 0; i--) 18 | { 19 | var overriden = _cachedAttributes[i].OverrideHeight(); 20 | if (overriden != null) return overriden.Value; 21 | } 22 | 23 | return base.GetPropertyHeight(property, label); 24 | } 25 | 26 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 27 | { 28 | CacheAttributes(); 29 | 30 | bool drawn = false; 31 | for (var i = _cachedAttributes.Length - 1; i >= 0; i--) 32 | { 33 | var ab = _cachedAttributes[i]; 34 | ab.ValidateProperty(property); 35 | 36 | ab.OnBeforeGUI(position, property, label); 37 | 38 | // Draw the things with higher priority first. If drawn once - skip drawing 39 | if (!drawn) 40 | { 41 | if (ab.OnGUI(position, property, label)) drawn = true; 42 | } 43 | 44 | ab.OnAfterGUI(position, property, label); 45 | } 46 | 47 | if (!drawn) EditorGUI.PropertyField(position, property, label); 48 | } 49 | 50 | private void CacheAttributes() 51 | { 52 | if (_cachedAttributes.IsNullOrEmpty()) 53 | { 54 | _cachedAttributes = fieldInfo 55 | .GetCustomAttributes(typeof(AttributeBase), false) 56 | .OrderBy(s => ((PropertyAttribute) s).order) 57 | .Select(a => a as AttributeBase).ToArray(); 58 | } 59 | } 60 | } 61 | } 62 | #endif -------------------------------------------------------------------------------- /Attributes/AttributeBaseDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ce6a191490f7425a984c36a53cebd36d 3 | timeCreated: 1582017102 -------------------------------------------------------------------------------- /Attributes/AutoPropertyAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5234d76d99eb402f89f4a35810990c26 3 | timeCreated: 1554718448 -------------------------------------------------------------------------------- /Attributes/ButtonMethodAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e96e2e6d8d1626c4abf4c413bc489af0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/CharactersRangeAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: add63a4947a64f2428030472426ecba4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/ConditionalFieldAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f0c8c14a34cc7b4c8ee94ff351a2902 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/ConstantsSelectionAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d93e4517d0ec49138d37edab20cacd2f 3 | timeCreated: 1582028131 -------------------------------------------------------------------------------- /Attributes/DefinedValuesAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bb25c9dc1c7ff1345ac286ba31c0af36 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/DisplayInspectorAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d0a699aecc941574e9faf6a546c0e663 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/DisplayPreviewAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace MyBox 5 | { 6 | public class DisplayPreviewAttribute : PropertyAttribute 7 | { 8 | public readonly int Width; 9 | public readonly int Height; 10 | 11 | public DisplayPreviewAttribute(int width = 70, int height = 70) 12 | { 13 | Width = width; 14 | Height = height; 15 | } 16 | } 17 | } 18 | 19 | #if UNITY_EDITOR 20 | namespace MyBox.Internal 21 | { 22 | using UnityEditor; 23 | 24 | [CustomPropertyDrawer(typeof(DisplayPreviewAttribute))] 25 | public class DrawSpriteDrawer : PropertyDrawer 26 | { 27 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) => 28 | ((DisplayPreviewAttribute)attribute).Height; 29 | 30 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 31 | { 32 | var width = ((DisplayPreviewAttribute)attribute).Width; 33 | var height = ((DisplayPreviewAttribute)attribute).Height; 34 | var fieldType = fieldInfo.FieldType.GetElementType() ?? fieldInfo.FieldType; 35 | 36 | 37 | EditorGUI.BeginProperty(new Rect(position.x, position.y, EditorGUIUtility.currentViewWidth, height), label, property); 38 | 39 | EditorGUI.LabelField(position, label); 40 | var previewRect = new Rect(position.x + EditorGUIUtility.labelWidth, position.y, width, height); 41 | 42 | if (IsImageType(fieldType) || property.objectReferenceValue == null) 43 | EditorGUI.ObjectField(previewRect, property, fieldType, GUIContent.none); 44 | else 45 | { 46 | var preview = AssetPreview.GetAssetPreview(property.objectReferenceValue); 47 | if (preview != null) previewRect.width += 18; 48 | EditorGUI.ObjectField(previewRect, property, fieldType, GUIContent.none); 49 | 50 | if (preview != null) 51 | { 52 | previewRect.width -= 20; 53 | previewRect.height -= 2; 54 | previewRect.x += 1; 55 | previewRect.y += 1; 56 | GUI.DrawTexture(previewRect, preview, ScaleMode.ScaleToFit); 57 | } 58 | } 59 | 60 | EditorGUI.EndProperty(); 61 | bool IsImageType(Type t) => t == typeof(Sprite) || t == typeof(Texture2D) || t == typeof(Texture); 62 | } 63 | } 64 | } 65 | #endif -------------------------------------------------------------------------------- /Attributes/DisplayPreviewAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 945f93293cd2e024eb8759ee2147d61f -------------------------------------------------------------------------------- /Attributes/FoldoutAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 69f6d9b4f0e9f594dbcc767598fe91c6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/InitializationFieldAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | /// 6 | /// Field will be Read-Only in Playmode 7 | /// 8 | public class InitializationFieldAttribute : PropertyAttribute 9 | { 10 | } 11 | } 12 | 13 | #if UNITY_EDITOR 14 | namespace MyBox.Internal 15 | { 16 | using UnityEditor; 17 | 18 | [CustomPropertyDrawer(typeof(InitializationFieldAttribute))] 19 | public class InitializationFieldAttributeDrawer : PropertyDrawer 20 | { 21 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 22 | { 23 | return EditorGUI.GetPropertyHeight(property, label, true); 24 | } 25 | 26 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 27 | { 28 | if (Application.isPlaying) GUI.enabled = false; 29 | EditorGUI.PropertyField(position, property, label, true); 30 | GUI.enabled = true; 31 | } 32 | } 33 | } 34 | #endif -------------------------------------------------------------------------------- /Attributes/InitializationFieldAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dd5ef49202d6492bb39be27d203b0163 3 | timeCreated: 1588577864 -------------------------------------------------------------------------------- /Attributes/LayerAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | public class LayerAttribute : PropertyAttribute 6 | { 7 | } 8 | } 9 | 10 | #if UNITY_EDITOR 11 | namespace MyBox.Internal 12 | { 13 | using UnityEditor; 14 | 15 | [CustomPropertyDrawer(typeof(LayerAttribute))] 16 | public class LayerAttributeDrawer : PropertyDrawer 17 | { 18 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 19 | { 20 | if (property.propertyType != SerializedPropertyType.Integer) 21 | { 22 | if (!_checked) Warning(property); 23 | EditorGUI.PropertyField(position, property, label); 24 | return; 25 | } 26 | 27 | property.intValue = EditorGUI.LayerField(position, label, property.intValue); 28 | } 29 | 30 | private bool _checked; 31 | 32 | private void Warning(SerializedProperty property) 33 | { 34 | Debug.LogWarning(string.Format("Property {0} in object {1} is of wrong type. Expected: Int", 35 | property.name, property.serializedObject.targetObject)); 36 | _checked = true; 37 | } 38 | } 39 | } 40 | #endif 41 | -------------------------------------------------------------------------------- /Attributes/LayerAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 979d3d332ae931a4f8dc8aaf52644f0c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/MaxValueAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8930225c73d74e5dbb7784e4c97eb1ef 3 | timeCreated: 1582014887 -------------------------------------------------------------------------------- /Attributes/MinMaxRangeAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aa6fba45efae4ac4b9830e11066fb969 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/MinValueAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7a6fc14799014e3ea82c8158bd477aca 3 | timeCreated: 1582013139 -------------------------------------------------------------------------------- /Attributes/MustBeAssignedAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cba7129e39e007e48a973ba3aa491562 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/MustBeAssignedConditionalFieldExclude.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using System.Linq; 4 | using System.Reflection; 5 | using UnityEditor; 6 | 7 | namespace MyBox.Internal 8 | { 9 | [InitializeOnLoad] 10 | public class MustBeAssignedConditionalFieldExclude 11 | { 12 | static MustBeAssignedConditionalFieldExclude() 13 | { 14 | MustBeAssignedAttributeChecker.ExcludeFieldFilter += ExcludeCheckIfConditionalFieldHidden; 15 | } 16 | 17 | private static readonly Type ConditionalType = typeof(ConditionalFieldAttribute); 18 | 19 | private static bool ExcludeCheckIfConditionalFieldHidden(FieldInfo field, UnityEngine.Object obj) 20 | { 21 | if (ConditionalType == null) return false; 22 | if (!field.IsDefined(ConditionalType, false)) return false; 23 | 24 | // Get a specific attribute of this field 25 | var conditional = field.GetCustomAttributes(ConditionalType, false) 26 | .Select(a => a as ConditionalFieldAttribute) 27 | .SingleOrDefault(); 28 | 29 | return conditional != null && !ConditionalUtility.IsConditionMatch(obj, conditional.Data); 30 | } 31 | } 32 | } 33 | #endif -------------------------------------------------------------------------------- /Attributes/MustBeAssignedConditionalFieldExclude.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e15cfc2935144103b5361ee1609fdae4 3 | timeCreated: 1564495831 -------------------------------------------------------------------------------- /Attributes/OverrideLabelAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | public class OverrideLabelAttribute : PropertyAttribute 6 | { 7 | public readonly string NewLabel; 8 | 9 | public OverrideLabelAttribute(string newLabel) => NewLabel = newLabel; 10 | } 11 | } 12 | 13 | #if UNITY_EDITOR 14 | namespace MyBox.Internal 15 | { 16 | using UnityEditor; 17 | 18 | [CustomPropertyDrawer(typeof(OverrideLabelAttribute))] 19 | public class OverrideLabelDrawer : PropertyDrawer 20 | { 21 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 22 | { 23 | var customDrawer = CustomDrawerUtility.GetPropertyDrawerForProperty(property, fieldInfo, attribute); 24 | if (customDrawer != null) return customDrawer.GetPropertyHeight(property, label); 25 | 26 | return EditorGUI.GetPropertyHeight(property, label); 27 | } 28 | 29 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 30 | { 31 | if (property.isArray) WarningsPool.LogCollectionsNotSupportedWarning(property, nameof(OverrideLabelAttribute)); 32 | 33 | label.text = ((OverrideLabelAttribute)attribute).NewLabel; 34 | 35 | var customDrawer = CustomDrawerUtility.GetPropertyDrawerForProperty(property, fieldInfo, attribute); 36 | if (customDrawer != null) customDrawer.OnGUI(position, property, label); 37 | else EditorGUI.PropertyField(position, property, label, true); 38 | } 39 | } 40 | } 41 | #endif -------------------------------------------------------------------------------- /Attributes/OverrideLabelAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a3118b2fddf33042bce8519708bf318 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/PositiveValueOnlyAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9f63e31912630bf4e88f4f2e9eab2f7b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/RangeVectorAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 40cde25a2fd60554596e6d0e8d38a593 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/ReadOnlyAttribute.cs: -------------------------------------------------------------------------------- 1 | #if !ODIN_INSPECTOR 2 | using UnityEngine; 3 | 4 | namespace MyBox 5 | { 6 | public enum ReadOnly 7 | { 8 | Always, 9 | PlayMode, 10 | EditTime 11 | } 12 | 13 | public class ReadOnlyAttribute : ConditionalFieldAttribute 14 | { 15 | public readonly ReadOnly ReadOnlyMode; 16 | 17 | public ReadOnlyAttribute(ReadOnly readOnly = ReadOnly.Always) => ReadOnlyMode = readOnly; 18 | 19 | /// String name of field to check value 20 | /// Inverse check result 21 | /// On which values' field will be shown in inspector 22 | public ReadOnlyAttribute(string fieldToCheck, bool inverse = false, params object[] compareValues) : base(fieldToCheck, inverse, compareValues) 23 | { } 24 | 25 | 26 | public ReadOnlyAttribute(string[] fieldToCheck, bool[] inverse = null, params object[] compare) : base(fieldToCheck, inverse, compare) 27 | { } 28 | 29 | public ReadOnlyAttribute(params string[] fieldToCheck) : base(fieldToCheck) 30 | { } 31 | 32 | public ReadOnlyAttribute(bool useMethod, string method, bool inverse = false) : base(useMethod, method, inverse) 33 | { } 34 | } 35 | } 36 | 37 | #if UNITY_EDITOR 38 | namespace MyBox.Internal 39 | { 40 | using UnityEditor; 41 | 42 | [CustomPropertyDrawer(typeof(ReadOnlyAttribute))] 43 | public class ReadOnlyAttributeDrawer : PropertyDrawer 44 | { 45 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 46 | { 47 | return EditorGUI.GetPropertyHeight(property, label, true); 48 | } 49 | 50 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 51 | { 52 | if (!(attribute is ReadOnlyAttribute conditional)) return; 53 | 54 | bool enabled = 55 | conditional.ReadOnlyMode != ReadOnly.Always ? ReadOnlyModeEditable() : 56 | !ConditionalUtility.IsPropertyConditionMatch(property, conditional.Data); 57 | 58 | GUI.enabled = enabled; 59 | EditorGUI.PropertyField(position, property, label, true); 60 | GUI.enabled = true; 61 | 62 | bool ReadOnlyModeEditable() 63 | { 64 | return conditional.ReadOnlyMode switch 65 | { 66 | ReadOnly.Always => false, 67 | ReadOnly.PlayMode => !Application.isPlaying, 68 | ReadOnly.EditTime => Application.isPlaying, 69 | _ => false 70 | }; 71 | } 72 | } 73 | } 74 | } 75 | #endif 76 | #endif 77 | -------------------------------------------------------------------------------- /Attributes/ReadOnlyAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 44c78368338beb948bdffa8db7179a0b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/RegexStringAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 38cf7a3ca1a04872b56d3cc1d90997b6 3 | timeCreated: 1623076361 -------------------------------------------------------------------------------- /Attributes/RequireLayerAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | [AttributeUsage(AttributeTargets.Class), PublicAPI] 8 | public class RequireLayerAttribute : Attribute 9 | { 10 | public readonly string LayerName; 11 | public readonly int LayerIndex = -1; 12 | 13 | public int RequiredLayerIndex => LayerName != null ? LayerMask.NameToLayer(LayerName) : LayerIndex; 14 | 15 | public RequireLayerAttribute(string layer) => LayerName = layer; 16 | public RequireLayerAttribute(int layer) => LayerIndex = layer; 17 | } 18 | } -------------------------------------------------------------------------------- /Attributes/RequireLayerAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a239ed93c95b4382a478c97d2bec7768 3 | timeCreated: 1567174003 -------------------------------------------------------------------------------- /Attributes/RequireLayerOtRagAttributeHandler.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | namespace MyBox.Internal 3 | { 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | [InitializeOnLoad] 8 | public class RequireLayerOtRagAttributeHandler 9 | { 10 | static RequireLayerOtRagAttributeHandler() 11 | { 12 | EditorApplication.playModeStateChanged += ProcessWhenPlaymodeStarts; 13 | } 14 | 15 | private static void ProcessWhenPlaymodeStarts(PlayModeStateChange _) 16 | { 17 | if (!EditorApplication.isPlayingOrWillChangePlaymode || EditorApplication.isPlaying) return; 18 | 19 | var components = Object.FindObjectsOfType(); 20 | foreach (var component in components) 21 | { 22 | foreach (var attribute in component.GetType().GetCustomAttributes(true)) 23 | { 24 | if (attribute is RequireLayerAttribute layerAttribute) 25 | { 26 | var requiredLayer = layerAttribute.RequiredLayerIndex; 27 | if (component.gameObject.layer == requiredLayer) continue; 28 | 29 | Debug.LogWarning("Layer of " + component.name + " changed by RequireLayerAttribute to " + layerAttribute.LayerName); 30 | component.gameObject.layer = requiredLayer; 31 | EditorUtility.SetDirty(component); 32 | } 33 | else 34 | if (attribute is RequireTagAttribute tagAttribute) 35 | { 36 | if (component.CompareTag(tagAttribute.Tag)) continue; 37 | 38 | Debug.LogWarning("Tag of " + component.name + " changed by RequireTagAttribute to " + tagAttribute.Tag); 39 | component.gameObject.tag = tagAttribute.Tag; 40 | EditorUtility.SetDirty(component); 41 | } 42 | } 43 | } 44 | } 45 | } 46 | } 47 | #endif 48 | -------------------------------------------------------------------------------- /Attributes/RequireLayerOtRagAttributeHandler.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 47e06842e3e6403d984cf0d03b3ff844 3 | timeCreated: 1567412996 -------------------------------------------------------------------------------- /Attributes/RequireTagAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MyBox 4 | { 5 | [AttributeUsage(AttributeTargets.Class)] 6 | public class RequireTagAttribute : Attribute 7 | { 8 | public string Tag; 9 | 10 | public RequireTagAttribute(string tag) 11 | { 12 | Tag = tag; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Attributes/RequireTagAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4ab3a785f0a04eeeb2b90de6430cef9e 3 | timeCreated: 1567412854 -------------------------------------------------------------------------------- /Attributes/SceneAttribute.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Author: Anton 3 | // https://github.com/antontidev 4 | // ---------------------------------------------------------------------------- 5 | 6 | using System; 7 | using System.Linq; 8 | using UnityEngine; 9 | 10 | namespace MyBox 11 | { 12 | /// 13 | /// Used to pick scene from inspector. 14 | /// Consider to use type instead as it is more flexible 15 | /// 16 | [AttributeUsage(AttributeTargets.Field)] 17 | public class SceneAttribute : PropertyAttribute 18 | { 19 | } 20 | } 21 | 22 | #if UNITY_EDITOR 23 | namespace MyBox.Internal 24 | { 25 | using UnityEditor; 26 | 27 | [CustomPropertyDrawer(typeof(SceneAttribute))] 28 | public class SceneDrawer : PropertyDrawer 29 | { 30 | private SceneAttribute _attribute; 31 | private string[] _scenesInBuild; 32 | private string[] _scenesInBuildFormatted; 33 | 34 | private void Initialize(string initialValue) 35 | { 36 | if (_attribute != null) return; 37 | 38 | _attribute = (SceneAttribute)attribute; 39 | 40 | _scenesInBuild = new string[EditorBuildSettings.scenes.Length + 1]; 41 | _scenesInBuildFormatted = new string[_scenesInBuild.Length]; 42 | 43 | for (var i = 0; i < EditorBuildSettings.scenes.Length; i++) 44 | { 45 | var scene = EditorBuildSettings.scenes[i].path.Split('/').Last().Replace(".unity", string.Empty); 46 | var formattedScene = scene + $" [{i}]"; 47 | _scenesInBuild[i + 1] = scene; 48 | _scenesInBuildFormatted[i + 1] = formattedScene; 49 | } 50 | 51 | var defaultValue = "NULL"; 52 | if (initialValue.NotNullOrEmpty() && CurrentIndex(initialValue) == 0) 53 | defaultValue = "NOT FOUND: " + initialValue; 54 | _scenesInBuildFormatted[0] = defaultValue; 55 | } 56 | 57 | private int CurrentIndex(string currentValue) 58 | { 59 | if (_scenesInBuild.Length <= 1 || currentValue.IsNullOrEmpty()) return 0; 60 | 61 | for (var i = 0; i < _scenesInBuild.Length; i++) 62 | { 63 | if (_scenesInBuild[i] == currentValue) return i; 64 | } 65 | 66 | return 0; 67 | } 68 | 69 | 70 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 71 | { 72 | if (property.propertyType != SerializedPropertyType.String) 73 | { 74 | EditorGUI.LabelField(position, label.text, "Use [Scene] with strings."); 75 | return; 76 | } 77 | Initialize(property.stringValue); 78 | 79 | 80 | var index = CurrentIndex(property.stringValue); 81 | var newIndex = EditorGUI.Popup(position, label.text, index, _scenesInBuildFormatted); 82 | if (newIndex != index) 83 | { 84 | property.stringValue = newIndex == 0 ? string.Empty : _scenesInBuild[newIndex]; 85 | property.serializedObject.ApplyModifiedProperties(); 86 | } 87 | } 88 | } 89 | } 90 | #endif -------------------------------------------------------------------------------- /Attributes/SceneAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f2e2f0d183cdeeb4a9e0d11deb8f782b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/SearchableEnumAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d4c1ac06e38adc9418191cf707dc1c63 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/SeparatorAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | public class SeparatorAttribute : PropertyAttribute 6 | { 7 | public readonly string Title; 8 | public readonly bool WithOffset; 9 | 10 | 11 | public SeparatorAttribute() 12 | { 13 | Title = ""; 14 | } 15 | 16 | public SeparatorAttribute(string title, bool withOffset = false) 17 | { 18 | Title = title; 19 | WithOffset = withOffset; 20 | } 21 | } 22 | } 23 | 24 | #if UNITY_EDITOR 25 | namespace MyBox.Internal 26 | { 27 | using UnityEditor; 28 | 29 | [CustomPropertyDrawer(typeof(SeparatorAttribute))] 30 | public class SeparatorAttributeDrawer : DecoratorDrawer 31 | { 32 | private SeparatorAttribute Separator => (SeparatorAttribute) attribute; 33 | 34 | public override float GetHeight() => Separator.WithOffset ? 40 : Separator.Title.IsNullOrEmpty() ? 28 : 32; 35 | 36 | public override void OnGUI(Rect position) 37 | { 38 | var title = Separator.Title; 39 | if (title.IsNullOrEmpty()) 40 | { 41 | position.height = 1; 42 | position.y += 14; 43 | 44 | DrawLine(position); 45 | } 46 | else 47 | { 48 | Vector2 textSize = GUI.skin.label.CalcSize(new GUIContent(title)); 49 | float separatorWidth = (position.width - textSize.x) / 2 - 5; 50 | position.y += 19; 51 | 52 | GUI.Box(new Rect(position.xMin, position.yMin, separatorWidth, 1), GUIContent.none); 53 | GUI.Label(new Rect(position.xMin + separatorWidth + 5, position.yMin - 10, textSize.x, 20), title); 54 | GUI.Box(new Rect(position.xMin + separatorWidth + 10 + textSize.x, position.yMin, separatorWidth, 1), GUIContent.none); 55 | } 56 | 57 | void DrawLine(Rect drawPosition) 58 | { 59 | if (Event.current.type != EventType.Repaint) return; 60 | GUI.skin.box.Draw(drawPosition, GUIContent.none, false, false, false, false); 61 | } 62 | } 63 | } 64 | } 65 | #endif -------------------------------------------------------------------------------- /Attributes/SeparatorAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5b55cf9f9427edf4f94a66bc2a6b14b3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/SpriteLayerAttribute.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Author: Kaynn, Yeo Wen Qin 3 | // https://github.com/Kaynn-Cahya 4 | // Date: 11/02/2019 5 | // ---------------------------------------------------------------------------- 6 | 7 | using UnityEngine; 8 | 9 | #if UNITY_EDITOR 10 | using UnityEditor; 11 | #endif 12 | 13 | namespace MyBox 14 | { 15 | public class SpriteLayerAttribute : PropertyAttribute 16 | { 17 | } 18 | } 19 | 20 | #if UNITY_EDITOR 21 | namespace MyBox.Internal 22 | { 23 | [CustomPropertyDrawer(typeof(SpriteLayerAttribute))] 24 | public class SpriteLayerAttributeDrawer : PropertyDrawer 25 | { 26 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 27 | { 28 | if (property.propertyType != SerializedPropertyType.Integer) 29 | { 30 | if (!_checkedType) PropertyTypeWarning(property); 31 | EditorGUI.PropertyField(position, property, label); 32 | return; 33 | } 34 | 35 | var spriteLayerNames = GetSpriteLayerNames(); 36 | HandleSpriteLayerSelectionUI(position, property, label, spriteLayerNames); 37 | } 38 | 39 | private bool _checkedType; 40 | private void PropertyTypeWarning(SerializedProperty property) 41 | { 42 | Debug.LogWarning(string.Format("Property {0} in object {1} is of wrong type. Expected: Int", 43 | property.name, property.serializedObject.targetObject)); 44 | _checkedType = true; 45 | } 46 | 47 | private void HandleSpriteLayerSelectionUI(Rect position, SerializedProperty property, GUIContent label, string[] spriteLayerNames) 48 | { 49 | EditorGUI.BeginProperty(position, label, property); 50 | 51 | // To show which sprite layer is currently selected. 52 | int currentSpriteLayerIndex; 53 | bool layerFound = TryGetSpriteLayerIndexFromProperty(out currentSpriteLayerIndex, spriteLayerNames, property); 54 | 55 | if (!layerFound) 56 | { 57 | // Set to default layer. (Previous layer was removed) 58 | Debug.Log(string.Format( 59 | "Property {0} in object {1} is set to the default layer. Reason: previously selected layer was removed.", 60 | property.name, property.serializedObject.targetObject)); 61 | property.intValue = 0; 62 | currentSpriteLayerIndex = 0; 63 | } 64 | 65 | int selectedSpriteLayerIndex = EditorGUI.Popup(position, label.text, currentSpriteLayerIndex, spriteLayerNames); 66 | 67 | // Change property value if user selects a new sprite layer. 68 | if (selectedSpriteLayerIndex != currentSpriteLayerIndex) 69 | { 70 | property.intValue = SortingLayer.NameToID(spriteLayerNames[selectedSpriteLayerIndex]); 71 | } 72 | 73 | EditorGUI.EndProperty(); 74 | } 75 | 76 | #region Util 77 | 78 | private bool TryGetSpriteLayerIndexFromProperty(out int index, string[] spriteLayerNames, SerializedProperty property) 79 | { 80 | // To keep the property's value consistent, after the layers have been sorted around. 81 | string layerName = SortingLayer.IDToName(property.intValue); 82 | 83 | // Return the index where on it matches. 84 | for (int i = 0; i < spriteLayerNames.Length; ++i) 85 | { 86 | if (spriteLayerNames[i].Equals(layerName)) 87 | { 88 | index = i; 89 | return true; 90 | } 91 | } 92 | 93 | // The current layer was removed. 94 | index = -1; 95 | return false; 96 | } 97 | 98 | private string[] GetSpriteLayerNames() 99 | { 100 | string[] result = new string[SortingLayer.layers.Length]; 101 | 102 | for (int i = 0; i < result.Length; ++i) 103 | { 104 | result[i] = SortingLayer.layers[i].name; 105 | } 106 | 107 | return result; 108 | } 109 | 110 | #endregion 111 | } 112 | } 113 | #endif -------------------------------------------------------------------------------- /Attributes/SpriteLayerAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1f05661da7d39cf418051ccfb13eb5a9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/TagAttribute.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Author: Kaynn, Yeo Wen Qin 3 | // https://github.com/Kaynn-Cahya 4 | // Date: 11/02/2019 5 | // ---------------------------------------------------------------------------- 6 | 7 | using UnityEngine; 8 | 9 | namespace MyBox 10 | { 11 | public class TagAttribute : PropertyAttribute 12 | { 13 | } 14 | } 15 | 16 | #if UNITY_EDITOR 17 | namespace MyBox.Internal 18 | { 19 | using UnityEditor; 20 | 21 | [CustomPropertyDrawer(typeof(TagAttribute))] 22 | public class TagAttributeDrawer : PropertyDrawer 23 | { 24 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 25 | { 26 | if (property.propertyType != SerializedPropertyType.String) 27 | { 28 | if (!_checked) Warning(property); 29 | EditorGUI.PropertyField(position, property, label); 30 | return; 31 | } 32 | 33 | property.stringValue = EditorGUI.TagField(position, label, property.stringValue); 34 | } 35 | 36 | private bool _checked; 37 | 38 | private void Warning(SerializedProperty property) 39 | { 40 | Debug.LogWarning(string.Format("Property {0} in object {1} is of wrong type. Expected: String", 41 | property.name, property.serializedObject.targetObject)); 42 | _checked = true; 43 | } 44 | } 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /Attributes/TagAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4112d636c944a774aae43810656bde88 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Attributes/TopmostComponentAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | /// 8 | /// MonoBehaviour with this attribute will be moved to top in the Inspector when added 9 | /// 10 | [AttributeUsage(AttributeTargets.Class), PublicAPI] 11 | public class TopmostComponentAttribute : Attribute 12 | { 13 | } 14 | } 15 | 16 | #if UNITY_EDITOR 17 | namespace MyBox.Internal 18 | { 19 | public static class TopmostComponentHandler 20 | { 21 | [UnityEditor.InitializeOnLoadMethod] 22 | private static void TestAddComponentReaction() 23 | { 24 | UnityEditor.ObjectFactory.componentWasAdded -= OnComponentAdded; 25 | UnityEditor.ObjectFactory.componentWasAdded += OnComponentAdded; 26 | 27 | void OnComponentAdded(Component component) 28 | { 29 | if (component.GetType().IsDefined(typeof(TopmostComponentAttribute), true)) 30 | MyComponentUtility.MoveComponentInspectorToTop(component); 31 | } 32 | } 33 | } 34 | } 35 | #endif -------------------------------------------------------------------------------- /Attributes/TopmostComponentAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 04adf87d6d554dd699d0844270c85cca 3 | timeCreated: 1705835674 -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 48881cb6a8fc44bba97eb256edc502c8 3 | timeCreated: 1565857492 -------------------------------------------------------------------------------- /Extensions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 54cf25d58c5fbd84288f3722696211f2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Extensions/EditorExtensions.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dd2b08b6aac506f4eabedf9dff5a11cb 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MyDefinesUtility.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | namespace MyBox.EditorTools 3 | { 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Reflection; 8 | using JetBrains.Annotations; 9 | using UnityEditor; 10 | 11 | /// 12 | /// Basically a copy-paste of Unity.VisualScripting.DefineUtility. 13 | /// Simplifies handling of PlayerSettings.Set(Get)ScriptingDefineSymbols 14 | /// 15 | [PublicAPI] 16 | public class MyDefinesUtility 17 | { 18 | private static IEnumerable buildTargetGroups 19 | { 20 | get 21 | { 22 | return Enum.GetValues(typeof(BuildTargetGroup)).Cast().Where 23 | (group => 24 | group != BuildTargetGroup.Unknown && 25 | typeof(BuildTargetGroup).GetField(group.ToString()).GetCustomAttribute(typeof(ObsoleteAttribute)) == null 26 | ); 27 | } 28 | } 29 | 30 | public static bool AddDefine(string define) 31 | { 32 | var added = false; 33 | 34 | foreach (var group in buildTargetGroups) 35 | { 36 | var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group).Split(';').Select(d => d.Trim()) 37 | .ToList(); 38 | 39 | if (!defines.Contains(define)) 40 | { 41 | defines.Add(define); 42 | PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", defines.ToArray())); 43 | added = true; 44 | } 45 | } 46 | 47 | return added; 48 | } 49 | 50 | public static bool RemoveDefine(string define) 51 | { 52 | var removed = false; 53 | 54 | foreach (var group in buildTargetGroups) 55 | { 56 | var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(group).Split(';').Select(d => d.Trim()) 57 | .ToList(); 58 | 59 | if (defines.Contains(define)) 60 | { 61 | defines.Remove(define); 62 | PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", defines.ToArray())); 63 | removed = true; 64 | } 65 | } 66 | 67 | return removed; 68 | } 69 | } 70 | } 71 | #endif -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MyDefinesUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a74181105a16463fbf581afb2dbd9768 3 | timeCreated: 1704808013 -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MyEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bca62b51cb1a1a1448d36f9c9881baff 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MyEditorAudio.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f72cf48ca3ff462aa3e2f45ec9abb67a 3 | timeCreated: 1655396168 -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MyGUI.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6be3865b984cad4488a515d4047a1e6c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MyHandles.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using JetBrains.Annotations; 3 | using UnityEditor; 4 | using UnityEngine; 5 | using UnityEngine.AI; 6 | 7 | namespace MyBox.EditorTools 8 | { 9 | [PublicAPI] 10 | public static class MyHandles 11 | { 12 | /// 13 | /// Draw line with arrows showing direction 14 | /// 15 | public static void DrawDirectionalLine(Vector3 fromPos, Vector3 toPos, float screenSpaceSize = 3, float arrowsDensity = .5f) 16 | { 17 | var arrowSize = screenSpaceSize / 4; 18 | 19 | Handles.DrawLine(fromPos, toPos); 20 | 21 | var direction = toPos - fromPos; 22 | var distance = Vector3.Distance(fromPos, toPos); 23 | var arrowsCount = (int) (distance / arrowsDensity); 24 | var delta = 1f / arrowsCount; 25 | for (int i = 1; i <= arrowsCount; i++) 26 | { 27 | var currentDelta = delta * i; 28 | var currentPosition = Vector3.Lerp(fromPos, toPos, currentDelta); 29 | DrawTinyArrow(currentPosition, direction, arrowSize); 30 | } 31 | } 32 | 33 | /// 34 | /// Draw arrow in position to direction 35 | /// 36 | public static void DrawTinyArrow(Vector3 position, Vector3 direction, float headLength = 0.25f, float headAngle = 20.0f) 37 | { 38 | var lookRotation = Quaternion.LookRotation(direction); 39 | var rightVector = new Vector3(0, 0, 1); 40 | Vector3 right = lookRotation * Quaternion.Euler(0, 180 + headAngle, 0) * rightVector; 41 | Vector3 left = lookRotation * Quaternion.Euler(0, 180 - headAngle, 0) * rightVector; 42 | Handles.DrawLine(position, position + right * headLength); 43 | Handles.DrawLine(position, position + left * headLength); 44 | } 45 | 46 | #if UNITY_AI_ENABLED 47 | 48 | /// 49 | /// Draw arrowed gizmo in scene view to visualize path 50 | /// 51 | public static void VisualizePath(NavMeshPath path) 52 | { 53 | var corners = path.corners; 54 | for (var i = 1; i < corners.Length; i++) 55 | { 56 | var cornerA = corners[i - 1]; 57 | var cornerB = corners[i]; 58 | var size = HandleUtility.GetHandleSize(new Vector3(cornerA.x, cornerA.y, cornerA.z)); 59 | DrawDirectionalLine(cornerA, cornerB, size, size); 60 | } 61 | } 62 | 63 | #endif 64 | 65 | /// 66 | /// Draw flying path of height prom pointA to pointB 67 | /// 68 | public static void DrawFlyPath(Vector3 pointA, Vector3 pointB, float height = 3) 69 | { 70 | var color = Handles.color; 71 | var pointAOffset = new Vector3(pointA.x, pointA.y + height, pointA.z); 72 | var pointBOffset = new Vector3(pointB.x, pointB.y + height, pointB.z); 73 | Handles.DrawBezier(pointA, pointB, pointAOffset, pointBOffset, color, null, 3); 74 | } 75 | } 76 | } 77 | #endif -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MyHandles.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d92acda10a85c7479df21d5537fd781 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MyIconPresets.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c2f80a0e28274befa5a705de0edbf6b2 3 | timeCreated: 1550247722 -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MyScriptableObject.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System.IO; 3 | using UnityEngine; 4 | using UnityEditor; 5 | 6 | namespace MyBox.EditorTools 7 | { 8 | public static class MyScriptableObject 9 | { 10 | /// 11 | /// Load all ScriptableObjects of type 12 | /// 13 | public static T[] LoadAssetsFromResources() where T : ScriptableObject 14 | { 15 | return Resources.FindObjectsOfTypeAll(); 16 | } 17 | 18 | /// 19 | /// Load all SO of type from Assets 20 | /// 21 | public static T[] LoadAssets() where T : ScriptableObject 22 | { 23 | string[] guids = AssetDatabase.FindAssets("t:" + typeof(T).Name); 24 | T[] a = new T[guids.Length]; 25 | for (int i = 0; i < guids.Length; i++) 26 | { 27 | string path = AssetDatabase.GUIDToAssetPath(guids[i]); 28 | a[i] = AssetDatabase.LoadAssetAtPath(path); 29 | } 30 | 31 | return a; 32 | } 33 | 34 | 35 | /// 36 | /// Create ScriptableObject asset of name in folder 37 | /// 38 | public static T CreateAsset(string name, string folder = "Assets") where T : ScriptableObject 39 | { 40 | if (string.IsNullOrEmpty(name)) 41 | { 42 | Debug.LogError("ScriptableObjectUtility caused: Create Asset failed because Name is empty"); 43 | return null; 44 | } 45 | 46 | string path = folder + "/" + name.Trim() + ".asset"; 47 | 48 | var instance = ScriptableObject.CreateInstance(); 49 | 50 | var fullPath = Path.GetFullPath(path); 51 | var directory = Path.GetDirectoryName(fullPath); 52 | if (directory != null) Directory.CreateDirectory(directory); 53 | 54 | AssetDatabase.CreateAsset(instance, AssetDatabase.GenerateUniqueAssetPath(path)); 55 | 56 | AssetDatabase.SaveAssets(); 57 | 58 | Debug.Log("Scriptable object asset created at " + path); 59 | 60 | return instance; 61 | } 62 | 63 | public static T CreateAssetWithFolderDialog(string filename) where T : ScriptableObject 64 | { 65 | var path = EditorUtility.SaveFolderPanel("Where to save", "Assets/", ""); 66 | if (path.Length <= 0) return null; 67 | var relativePath = "Assets" + path.Substring(Application.dataPath.Length); 68 | 69 | return CreateAsset(filename, relativePath); 70 | } 71 | } 72 | } 73 | #endif -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MyScriptableObject.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8171f05d7a400964480544072bdb0e1b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/EditorExtensions/MySerializedProperty.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1647a9f1d48b4cdcbc9d8c0ed8ec8c5d 3 | timeCreated: 1550229037 -------------------------------------------------------------------------------- /Extensions/MyAlgorithms.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using JetBrains.Annotations; 3 | 4 | namespace MyBox 5 | { 6 | /// 7 | [PublicAPI] 8 | public static class MyAlgorithms 9 | { 10 | /// 11 | /// Convert to a different type 12 | /// 13 | public static T Cast(this IConvertible source) => (T)Convert.ChangeType(source, typeof(T)); 14 | 15 | /// 16 | /// Check if this is a particular type. 17 | /// 18 | public static bool Is(this object source) => source is T; 19 | 20 | /// 21 | /// Cast to a different type, exception-safe. 22 | /// 23 | public static T As(this object source) where T : class => source as T; 24 | 25 | /// 26 | /// Take an object and pass it as an argument to a void function. 27 | /// 28 | public static T Pipe(this T argument, Action action) 29 | { 30 | action(argument); 31 | return argument; 32 | } 33 | 34 | /// 35 | /// Take an object, pass it as an argument to a function, return the result. 36 | /// 37 | public static TResult Pipe(this T argument, Func function) => function(argument); 38 | 39 | /// 40 | /// Take an object, pass it as an argument to a function, return the object. 41 | /// 42 | public static T PipeKeep(this T argument, Func function) 43 | { 44 | function(argument); 45 | return argument; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Extensions/MyAlgorithms.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f124183e25b4eb04681a42b28f6b3cb7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyCollections.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6de18df9fa1208947a40cdd99eaf83f5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyColor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace MyBox 5 | { 6 | public static class MyColor 7 | { 8 | public static Color RandomBright => new Color(Random.Range(.4f, 1), Random.Range(.4f, 1), Random.Range(.4f, 1)); 9 | 10 | public static Color RandomDim => new Color(Random.Range(.4f, .6f), Random.Range(.4f, .8f), Random.Range(.4f, .8f)); 11 | 12 | public static Color RandomColor => new Color(Random.Range(.1f, .9f), Random.Range(.1f, .9f), Random.Range(.1f, .9f)); 13 | 14 | /// 15 | /// Returns new Color with Alpha set to a 16 | /// 17 | public static Color WithAlphaSetTo(this Color color, float a) => new Color(color.r, color.g, color.b, a); 18 | 19 | /// 20 | /// Set Alpha of Image.Color 21 | /// 22 | public static void SetAlpha(this Graphic graphic, float a) => graphic.color = graphic.color.WithAlphaSetTo(a); 23 | 24 | /// 25 | /// Set Alpha of Renderer.Color 26 | /// 27 | public static void SetAlpha(this SpriteRenderer renderer, float a) => renderer.color = renderer.color.WithAlphaSetTo(a); 28 | 29 | /// 30 | /// To string of "#b5ff4f" format 31 | /// 32 | public static string ToHex(this Color color) => $"#{(int)(color.r * 255):X2}{(int)(color.g * 255):X2}{(int)(color.b * 255):X2}"; 33 | 34 | private const float LightOffset = 0.0625f; 35 | 36 | /// 37 | /// Returns a color lighter than the given color. 38 | /// 39 | public static Color Lighter(this Color color) => color.BrightnessOffset(LightOffset); 40 | 41 | /// 42 | /// Returns a color darker than the given color. 43 | /// 44 | public static Color Darker(this Color color) => color.BrightnessOffset(-LightOffset); 45 | 46 | /// 47 | /// Brightness offset with 1 is brightest and -1 is darkest 48 | /// 49 | public static Color BrightnessOffset(this Color color, float offset) 50 | => new Color(color.r + offset, color.g + offset, color.b + offset, color.a); 51 | 52 | /// 53 | /// Converts a HTML color string into UnityEngine.Color. 54 | /// See UnityEngine.ColorUtility.TryParseHtmlString for conversion conditions. 55 | /// 56 | public static Color ToUnityColor(this string source) 57 | { 58 | ColorUtility.TryParseHtmlString(source, out Color res); 59 | return res; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /Extensions/MyColor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e68d75d0410432b41b3c7b066b4cb6fa 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyCommonConstants.cs: -------------------------------------------------------------------------------- 1 | namespace MyBox 2 | { 3 | public static class MyCommonConstants 4 | { 5 | public static readonly System.Random SystemRandom = new System.Random(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Extensions/MyCommonConstants.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb2aa8c92e6ec874891ff512be617e27 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyComponentUtility.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | using UnityEngine; 3 | 4 | namespace MyBox 5 | { 6 | [PublicAPI] 7 | public static class MyComponentUtility 8 | { 9 | public static void MoveComponentInspectorToTop(Component component) 10 | { 11 | #if UNITY_EDITOR 12 | while (UnityEditorInternal.ComponentUtility.MoveComponentUp(component)){} 13 | #endif 14 | } 15 | 16 | public static void MoveComponentInspectorToBottom(Component component) 17 | { 18 | #if UNITY_EDITOR 19 | while (UnityEditorInternal.ComponentUtility.MoveComponentDown(component)){} 20 | #endif 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Extensions/MyComponentUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 90a89666e8ba462ba23529b4bdb88f97 3 | timeCreated: 1705654343 -------------------------------------------------------------------------------- /Extensions/MyCoroutines.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using MyBox.Internal; 4 | using UnityEngine; 5 | using Object = UnityEngine.Object; 6 | 7 | namespace MyBox 8 | { 9 | public static class MyCoroutines 10 | { 11 | private static CoroutineOwner CoroutineOwner 12 | { 13 | get 14 | { 15 | if (_coroutineOwner != null) return _coroutineOwner; 16 | 17 | var go = new GameObject("Static Coroutine Owner"); 18 | Object.DontDestroyOnLoad(go); 19 | go.hideFlags = HideFlags.HideAndDontSave; 20 | 21 | _coroutineOwner = go.AddComponent(); 22 | 23 | return _coroutineOwner; 24 | } 25 | } 26 | 27 | private static CoroutineOwner _coroutineOwner; 28 | 29 | /// 30 | /// StartCoroutine without MonoBehaviour 31 | /// 32 | public static Coroutine StartCoroutine(this IEnumerator coroutine) 33 | => CoroutineOwner.StartCoroutine(coroutine); 34 | 35 | /// 36 | /// Start next coroutine after this one 37 | /// 38 | public static Coroutine StartNext(this Coroutine coroutine, IEnumerator nextCoroutine) 39 | => StartCoroutine(StartNextCoroutine(coroutine, nextCoroutine)); 40 | 41 | public static Coroutine OnComplete(this Coroutine coroutine, Action onComplete) 42 | => StartCoroutine(OnCompleteCoroutine(coroutine, onComplete)); 43 | 44 | /// 45 | /// Stop coroutine started with MyCoroutines.StartCoroutine 46 | /// 47 | public static void StopCoroutine(Coroutine coroutine) => CoroutineOwner.StopCoroutine(coroutine); 48 | 49 | /// 50 | /// Stop all coroutines started with MyCoroutines.StartCoroutine 51 | /// 52 | public static void StopAllCoroutines() => CoroutineOwner.StopAllCoroutines(); 53 | 54 | /// 55 | /// CoroutineGroup allows to start bunch coroutines in one group 56 | /// and check the amount of running coroutines (or if there is any of them) 57 | /// 58 | public static CoroutineGroup CreateGroup(MonoBehaviour owner = null) 59 | => new CoroutineGroup(owner != null ? owner : CoroutineOwner); 60 | 61 | 62 | private static IEnumerator StartNextCoroutine(Coroutine coroutine, IEnumerator nextCoroutine) 63 | { 64 | yield return coroutine; 65 | yield return StartCoroutine(nextCoroutine); 66 | } 67 | 68 | private static IEnumerator OnCompleteCoroutine(Coroutine coroutine, Action onComplete) 69 | { 70 | yield return coroutine; 71 | onComplete?.Invoke(); 72 | } 73 | } 74 | } 75 | 76 | namespace MyBox.Internal 77 | { 78 | internal class CoroutineOwner : MonoBehaviour 79 | { 80 | } 81 | } -------------------------------------------------------------------------------- /Extensions/MyCoroutines.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 785844a94ee84f97aed9365809940055 3 | timeCreated: 1565249278 -------------------------------------------------------------------------------- /Extensions/MyDebug.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2dcf836d03824e647a22dde16fb8be00 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyDelayedActions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using UnityEngine; 4 | using UnityEngine.EventSystems; 5 | 6 | namespace MyBox 7 | { 8 | public static class MyDelayedActions 9 | { 10 | /// 11 | /// Invoke Action on Delay 12 | /// 13 | public static Coroutine DelayedAction(float waitSeconds, Action action, bool unscaled = false) 14 | { 15 | return DelayedActionCoroutine(waitSeconds, action, unscaled).StartCoroutine(); 16 | } 17 | 18 | 19 | /// 20 | /// Invoke Action next frame 21 | /// 22 | public static void DelayedAction(Action action) 23 | { 24 | Coroutine().StartCoroutine(); 25 | 26 | IEnumerator Coroutine() 27 | { 28 | yield return null; 29 | action?.Invoke(); 30 | } 31 | } 32 | 33 | /// 34 | /// Invoke Action on Delay 35 | /// 36 | public static Coroutine DelayedAction(this MonoBehaviour invoker, float waitSeconds, Action action, bool unscaled = false) 37 | { 38 | return invoker.StartCoroutine(DelayedActionCoroutine(waitSeconds, action, unscaled)); 39 | } 40 | 41 | /// 42 | /// Invoke Action next frame 43 | /// 44 | public static Coroutine DelayedAction(this MonoBehaviour invoker, Action action) 45 | { 46 | return invoker.StartCoroutine(Coroutine()); 47 | 48 | IEnumerator Coroutine() 49 | { 50 | yield return null; 51 | action?.Invoke(); 52 | } 53 | } 54 | 55 | 56 | /// 57 | /// Set GO as selected next frame (EventSystem.current.SetSelectedGameObject) 58 | /// 59 | public static IEnumerator DelayedUiSelection(GameObject objectToSelect) 60 | { 61 | yield return null; 62 | EventSystem.current.SetSelectedGameObject(null); 63 | EventSystem.current.SetSelectedGameObject(objectToSelect); 64 | } 65 | 66 | /// 67 | /// Set GO as selected next frame (EventSystem.current.SetSelectedGameObject) 68 | /// 69 | public static Coroutine DelayedUiSelection(this MonoBehaviour invoker, GameObject objectToSelect) 70 | { 71 | return invoker.StartCoroutine(DelayedUiSelection(objectToSelect)); 72 | } 73 | 74 | 75 | private static IEnumerator DelayedActionCoroutine(float waitSeconds, Action action, bool unscaled = false) 76 | { 77 | if (unscaled) yield return new WaitForSecondsRealtime(waitSeconds); 78 | else yield return new WaitForSeconds(waitSeconds); 79 | 80 | if (action != null) action.Invoke(); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /Extensions/MyDelayedActions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8ba7897fc0e165a4ebe8e36b85556ec7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1aec7805ba997fb45b4db55a169a237e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyGizmos.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | public static class MyGizmos 6 | { 7 | public static void DrawArrow(Vector3 from, Vector3 direction, float headLength = 0.25f, float headAngle = 20.0f) 8 | { 9 | #if UNITY_EDITOR 10 | Gizmos.DrawRay(from, direction); 11 | 12 | Vector3 right = Quaternion.LookRotation(direction) * Quaternion.Euler(180 + headAngle, 0, 180 + headAngle) * new Vector3(0, 0, 1); 13 | Vector3 left = Quaternion.LookRotation(direction) * Quaternion.Euler(180 - headAngle, 0, 180 - headAngle) * new Vector3(0, 0, 1); 14 | Gizmos.DrawRay(from + direction, right * headLength); 15 | Gizmos.DrawRay(from + direction, left * headLength); 16 | #endif 17 | } 18 | 19 | public static void DrawSegment(Vector3 from, Vector3 to, float capSize = 0.1f) 20 | { 21 | Gizmos.DrawLine(from, to); 22 | Gizmos.DrawLine(from.OffsetY(-capSize), from.OffsetY(capSize)); 23 | Gizmos.DrawLine(to.OffsetY(-capSize), to.OffsetY(capSize)); 24 | } 25 | 26 | #if UNITY_PHYSICS2D_ENABLED 27 | public static void DrawBoxCollider2D(BoxCollider2D collider, bool fill = true) 28 | { 29 | var target = collider.transform; 30 | 31 | Gizmos.matrix = Matrix4x4.TRS(target.position, target.rotation, target.lossyScale); 32 | if (fill) Gizmos.DrawCube(collider.offset, collider.size); 33 | else Gizmos.DrawWireCube(collider.offset, collider.size); 34 | Gizmos.matrix = Matrix4x4.identity; 35 | } 36 | #endif 37 | } 38 | } -------------------------------------------------------------------------------- /Extensions/MyGizmos.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 804109ef525642fbaee14eea876599fd 3 | timeCreated: 1557482430 -------------------------------------------------------------------------------- /Extensions/MyInput.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 342ab573c5061db4f873c516dfe88822 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyLayers.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | using UnityEngine; 3 | 4 | namespace MyBox 5 | { 6 | [PublicAPI] 7 | public static class MyLayers 8 | { 9 | public static LayerMask AddLayer(LayerMask mask, int layer) 10 | => mask | (1 << layer); 11 | public static LayerMask AddLayer(LayerMask mask, string layer) 12 | => AddLayer(mask, LayerMask.NameToLayer(layer)); 13 | 14 | public static LayerMask RemoveLayer(LayerMask mask, int layer) 15 | => mask & ~(1 << layer); 16 | public static LayerMask RemoveLayer(LayerMask mask, string layer) 17 | => RemoveLayer(mask, LayerMask.NameToLayer(layer)); 18 | 19 | public static LayerMask ToggleLayer(LayerMask mask, int layer) 20 | => mask ^ (1 << layer); 21 | public static LayerMask ToggleLayer(LayerMask mask, string layer) 22 | => ToggleLayer(mask, LayerMask.NameToLayer(layer)); 23 | 24 | public static LayerMask SetLayer(LayerMask mask, int layer, bool include) 25 | => include ? AddLayer(mask, layer) : RemoveLayer(mask, layer); 26 | public static LayerMask SetLayer(LayerMask mask, string layer, bool include) 27 | => SetLayer(mask, LayerMask.NameToLayer(layer), include); 28 | 29 | public static LayerMask ToLayerMask(int layer) 30 | => 1 << layer; 31 | public static LayerMask ToLayerMask(string layer) 32 | => ToLayerMask(LayerMask.NameToLayer(layer)); 33 | 34 | public static bool LayerInMask(this LayerMask mask, int layer) 35 | => ((1 << layer) & mask) != 0; 36 | public static bool LayerInMask(this LayerMask mask, string layer) 37 | => LayerInMask(mask, LayerMask.NameToLayer(layer)); 38 | } 39 | } -------------------------------------------------------------------------------- /Extensions/MyLayers.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1384bb44b455c8f4ab5532ea77e23655 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyMath.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bd752117992a3d143aff581f379f41fc 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyNavMesh.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using UnityEngine.AI; 4 | 5 | namespace MyBox 6 | { 7 | #if UNITY_AI_ENABLED 8 | 9 | public static class MyNavMesh 10 | { 11 | /// 12 | /// Get length of path (combining all corners) 13 | /// 14 | /// Path to calculate 15 | /// Length in Units 16 | public static float GetLength(this NavMeshPath path) 17 | { 18 | var corners = path.corners; 19 | float length = 0; 20 | for (var i = 1; i < corners.Length; i++) 21 | { 22 | length += Vector3.Distance(corners[i - 1], corners[i]); 23 | } 24 | 25 | return length; 26 | } 27 | 28 | /// 29 | /// Roughly calculate time to traverse the path with given speed 30 | /// 31 | /// Path to calculate 32 | /// Speed of the agent 33 | /// Time in seconds 34 | public static float GetTimeToPass(this NavMeshPath path, float speed) 35 | { 36 | var length = path.GetLength(); 37 | float time = length / speed; 38 | time += (path.corners.Length - 1) * .5f; // slowdown on corners offset 39 | return time; 40 | } 41 | 42 | /// 43 | /// Get point on path 44 | /// 45 | /// Path to calculate 46 | /// Percent on path, from 0 to 1 47 | public static Vector3 GetPointOnPath(this NavMeshPath path, float rate) 48 | { 49 | rate = Mathf.Clamp01(rate); 50 | var length = path.GetLength(); 51 | float elapsedRate = 0; 52 | for (var i = 1; i < path.corners.Length; i++) 53 | { 54 | var from = path.corners[i - 1]; 55 | var to = path.corners[i]; 56 | var pieceLength = Vector3.Distance(from, to); 57 | var pieceRate = pieceLength / length; 58 | elapsedRate += pieceRate; 59 | 60 | if (rate <= elapsedRate) 61 | { 62 | var rateOffset = elapsedRate - rate; 63 | var rateOnPiece = 1 - rateOffset / pieceRate; 64 | return Vector3.Lerp(from, to, rateOnPiece); 65 | } 66 | } 67 | 68 | return path.corners[path.corners.Length - 1]; 69 | } 70 | 71 | /// 72 | /// Split path on points with defined distance 73 | /// 74 | /// Path to calculate 75 | /// Distance between points on path 76 | public static IEnumerable GetPointsOnPath(this NavMeshPath path, float distance = 1) 77 | { 78 | float pieceTraversedDistance = 0; 79 | for (var i = 1; i < path.corners.Length; i++) 80 | { 81 | var from = path.corners[i - 1]; 82 | var to = path.corners[i]; 83 | var pieceLength = Vector3.Distance(from, to); 84 | 85 | while (pieceTraversedDistance < pieceLength + distance) 86 | { 87 | var pointRatio = pieceTraversedDistance / pieceLength; 88 | yield return Vector3.Lerp(from, to, pointRatio); 89 | pieceTraversedDistance += distance; 90 | } 91 | pieceTraversedDistance -= pieceLength; 92 | } 93 | } 94 | } 95 | 96 | #endif 97 | } -------------------------------------------------------------------------------- /Extensions/MyNavMesh.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 125c702ea7344424c978c39852d0004f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyObsoleteExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace MyBox 5 | { 6 | public static class MyObsoleteExtensions 7 | { 8 | [Obsolete("1.6.3: Use MyCollections.GetOrAdd instead")] 9 | public static TValue GetOrDefault( 10 | this IDictionary source, 11 | TKey key, 12 | TValue customDefault = default(TValue)) => source.GetOrAdd(key, customDefault); 13 | 14 | [Obsolete("1.6.3: Use MyCollections.GetOrAdd instead")] 15 | public static TValue GetOrDefault( 16 | this IDictionary source, 17 | TKey key, 18 | Func customDefaultGenerator) => source.GetOrAdd(key, customDefaultGenerator()); 19 | } 20 | } -------------------------------------------------------------------------------- /Extensions/MyObsoleteExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 885e433f51cc4f69bbca87b575fa41eb 3 | timeCreated: 1622206116 -------------------------------------------------------------------------------- /Extensions/MyPhysics.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | public static class MyPhysics 6 | { 7 | #if UNITY_PHYSICS_ENABLED 8 | 9 | /// 10 | /// Sets the state of constraints for the source Rigidbody. 11 | /// 12 | public static Rigidbody ToggleConstraints(this Rigidbody source, 13 | RigidbodyConstraints constraints, 14 | bool state) 15 | { 16 | source.constraints = source.constraints.BitwiseToggle(constraints, state); 17 | return source; 18 | } 19 | 20 | #endif 21 | 22 | #if UNITY_PHYSICS2D_ENABLED 23 | 24 | /// 25 | /// Sets the state of constraints for the source Rigidbody2D. 26 | /// 27 | public static Rigidbody2D ToggleConstraints(this Rigidbody2D source, 28 | RigidbodyConstraints2D constraints, 29 | bool state) 30 | { 31 | source.constraints = source.constraints.BitwiseToggle(constraints, state); 32 | return source; 33 | } 34 | 35 | #endif 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Extensions/MyPhysics.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 930598581d4ea624c9cb11353c2f80c2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyPhysicsExtensions.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | public static class MyPhysicsExtensions 6 | { 7 | #if UNITY_PHYSICS_ENABLED 8 | 9 | /// 10 | /// Sets the state of the source enum, chosen by the 1-bits in the specified bit mask. 11 | /// 12 | public static RigidbodyConstraints BitwiseToggle(this RigidbodyConstraints source, RigidbodyConstraints bitMask, bool state) 13 | => state ? (source | bitMask) : (source & ~bitMask); 14 | 15 | #endif 16 | 17 | #if UNITY_PHYSICS2D_ENABLED 18 | 19 | /// 20 | /// Sets the state of the source enum, chosen by the 1-bits in the specified bit mask. 21 | /// 22 | public static RigidbodyConstraints2D BitwiseToggle(this RigidbodyConstraints2D source, RigidbodyConstraints2D bitMask, bool state) 23 | => state ? (source | bitMask) : (source & ~bitMask); 24 | 25 | #endif 26 | } 27 | } -------------------------------------------------------------------------------- /Extensions/MyPhysicsExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2c13ec89a242490c865fa65eaf09c898 3 | timeCreated: 1656944529 -------------------------------------------------------------------------------- /Extensions/MyQuaternionExtensions.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | using UnityEngine; 3 | 4 | namespace MyBox 5 | { 6 | [PublicAPI] 7 | public static class MyQuaternionExtensions 8 | { 9 | public static Quaternion SetEulerX(this Quaternion quaternion, float x) 10 | => Quaternion.Euler(quaternion.eulerAngles.SetX(x)); 11 | 12 | public static Quaternion SetEulerY(this Quaternion quaternion, float y) 13 | => Quaternion.Euler(quaternion.eulerAngles.SetY(y)); 14 | 15 | public static Quaternion SetEulerZ(this Quaternion quaternion, float z) 16 | => Quaternion.Euler(quaternion.eulerAngles.SetZ(z)); 17 | 18 | public static Quaternion SetEulerXY(this Quaternion quaternion, float x, float y) 19 | => Quaternion.Euler(quaternion.eulerAngles.SetXY(x, y)); 20 | 21 | public static Quaternion SetEulerXZ(this Quaternion quaternion, float x, float z) 22 | => Quaternion.Euler(quaternion.eulerAngles.SetXZ(x, z)); 23 | 24 | public static Quaternion SetEulerYZ(this Quaternion quaternion, float y, float z) 25 | => Quaternion.Euler(quaternion.eulerAngles.SetYZ(y, z)); 26 | } 27 | } -------------------------------------------------------------------------------- /Extensions/MyQuaternionExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 167efd4d91a646c48ff7d1f3adc0f173 3 | timeCreated: 1720428320 -------------------------------------------------------------------------------- /Extensions/MyReflection.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using JetBrains.Annotations; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | [PublicAPI] 8 | public static class MyReflection 9 | { 10 | public static bool HasMethod(this object target, string methodName) 11 | => target.GetType().GetMethod(methodName) != null; 12 | 13 | public static bool HasField(this object target, string fieldName) 14 | => target.GetType().GetField(fieldName) != null; 15 | 16 | public static bool HasProperty(this object target, string propertyName) 17 | => target.GetType().GetProperty(propertyName) != null; 18 | 19 | public static T GetPrivateField(this object target, string fieldName) 20 | { 21 | if (target == null) 22 | { 23 | Debug.LogError("Trying to get field from null"); 24 | return default; 25 | } 26 | 27 | if (fieldName.IsNullOrEmpty()) 28 | { 29 | Debug.LogError("Trying to fet unspecified field"); 30 | return default; 31 | } 32 | 33 | var field = target.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); 34 | if (field == null) 35 | { 36 | Debug.LogError($"Field {fieldName} not found in {target.GetType()}"); 37 | return default; 38 | } 39 | 40 | return (T)field.GetValue(target); 41 | } 42 | 43 | public static void SetPrivateField(this object target, string fieldName, T value) 44 | { 45 | if (target == null) 46 | { 47 | Debug.LogError("Trying to set field to null"); 48 | return; 49 | } 50 | 51 | if (fieldName.IsNullOrEmpty()) 52 | { 53 | Debug.LogError("Trying to set unspecified field"); 54 | return; 55 | } 56 | 57 | var field = target.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); 58 | if (field == null) 59 | { 60 | Debug.LogError($"Field {fieldName} not found in {target.GetType()}"); 61 | return; 62 | } 63 | 64 | if (field.FieldType != typeof(T)) 65 | { 66 | Debug.LogError($"Field {fieldName} is of type {field.FieldType} while trying to set {value.GetType()}"); 67 | return; 68 | } 69 | 70 | field.SetValue(target, value); 71 | } 72 | 73 | 74 | public static T GetPrivateProperty(this object target, string propertyName) 75 | { 76 | if (target == null) 77 | { 78 | Debug.LogError("Trying to get property from null"); 79 | return default; 80 | } 81 | 82 | if (propertyName.IsNullOrEmpty()) 83 | { 84 | Debug.LogError("Trying to get unspecified property"); 85 | return default; 86 | } 87 | 88 | var property = target.GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic); 89 | if (property == null) 90 | { 91 | Debug.LogError($"Property {propertyName} not found in {target.GetType()}"); 92 | return default; 93 | } 94 | 95 | return (T)property.GetValue(target); 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /Extensions/MyReflection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da93a62ca21e462ea375942c000207ae 3 | timeCreated: 1593627020 -------------------------------------------------------------------------------- /Extensions/MyRegex.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Text.RegularExpressions; 3 | 4 | namespace MyBox 5 | { 6 | public static class MyRegex 7 | { 8 | public const string WholeNumber = @"^-?\d+$"; 9 | public const string FloatingNumber = @"^-?\d*(\.\d+)?$"; 10 | 11 | public const string AlphanumericWithoutSpace = @"^[a-zA-Z0-9]*$"; 12 | public const string AlphanumericWithSpace = @"^[a-zA-Z0-9 ]*$"; 13 | 14 | public const string Email = @"^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})*$"; 15 | public const string URL = @"(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)"; 16 | 17 | 18 | /// 19 | /// Replace all but matching parts of the input string 20 | /// 21 | public static string KeepMatching(this Regex regex, string input) => regex.Matches(input).Cast() 22 | .Aggregate(string.Empty, (a, m) => a + m.Value); 23 | } 24 | } -------------------------------------------------------------------------------- /Extensions/MyRegex.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1403a06229e54d928e7366105c447cb7 3 | timeCreated: 1623083222 -------------------------------------------------------------------------------- /Extensions/MyString.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca83589ffd3d55f40be15399219bd59e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyTexture.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | public static class MyTexture 6 | { 7 | /// 8 | /// Create new sprite out of Texture 9 | /// 10 | public static Sprite AsSprite(this Texture2D texture) 11 | { 12 | var rect = new Rect(0, 0, texture.width, texture.height); 13 | var pivot = new Vector2(0.5f, 0.5f); 14 | return Sprite.Create(texture, rect, pivot); 15 | } 16 | 17 | /// 18 | /// Change texture size (and scale accordingly) 19 | /// 20 | public static Texture2D Resample(this Texture2D source, int targetWidth, int targetHeight) 21 | { 22 | int sourceWidth = source.width; 23 | int sourceHeight = source.height; 24 | float sourceAspect = (float) sourceWidth / sourceHeight; 25 | float targetAspect = (float) targetWidth / targetHeight; 26 | 27 | int xOffset = 0; 28 | int yOffset = 0; 29 | float factor; 30 | 31 | if (sourceAspect > targetAspect) 32 | { 33 | // crop width 34 | factor = (float) targetHeight / sourceHeight; 35 | xOffset = (int) ((sourceWidth - sourceHeight * targetAspect) * 0.5f); 36 | } 37 | else 38 | { 39 | // crop height 40 | factor = (float) targetWidth / sourceWidth; 41 | yOffset = (int) ((sourceHeight - sourceWidth / targetAspect) * 0.5f); 42 | } 43 | 44 | var data = source.GetPixels32(); 45 | var data2 = new Color32[targetWidth * targetHeight]; 46 | for (int y = 0; y < targetHeight; y++) 47 | { 48 | for (int x = 0; x < targetWidth; x++) 49 | { 50 | var p = new Vector2(Mathf.Clamp(xOffset + x / factor, 0, sourceWidth - 1), Mathf.Clamp(yOffset + y / factor, 0, sourceHeight - 1)); 51 | // bilinear filtering 52 | var c11 = data[Mathf.FloorToInt(p.x) + sourceWidth * (Mathf.FloorToInt(p.y))]; 53 | var c12 = data[Mathf.FloorToInt(p.x) + sourceWidth * (Mathf.CeilToInt(p.y))]; 54 | var c21 = data[Mathf.CeilToInt(p.x) + sourceWidth * (Mathf.FloorToInt(p.y))]; 55 | var c22 = data[Mathf.CeilToInt(p.x) + sourceWidth * (Mathf.CeilToInt(p.y))]; 56 | 57 | data2[x + y * targetWidth] = Color.Lerp(Color.Lerp(c11, c12, p.y), Color.Lerp(c21, c22, p.y), p.x); 58 | } 59 | } 60 | 61 | var tex = new Texture2D(targetWidth, targetHeight); 62 | tex.SetPixels32(data2); 63 | tex.Apply(true); 64 | return tex; 65 | } 66 | 67 | /// 68 | /// Crop texture to desired size. 69 | /// Somehow cropped image seemed darker, brightness offset may fix this 70 | /// 71 | public static Texture2D Crop(this Texture2D original, int left, int right, int top, int down, float brightnessOffset = 0) 72 | { 73 | int x = left + right; 74 | int y = top + down; 75 | int resW = original.width - x; 76 | int resH = original.height - y; 77 | var pixels = original.GetPixels(left, down, resW, resH); 78 | 79 | if (!Mathf.Approximately(brightnessOffset, 0)) 80 | { 81 | for (var i = 0; i < pixels.Length; i++) 82 | { 83 | pixels[i] = pixels[i].BrightnessOffset(brightnessOffset); 84 | } 85 | } 86 | 87 | Texture2D result = new Texture2D(resW, resH, TextureFormat.RGB24, false); 88 | result.SetPixels(pixels); 89 | result.Apply(); 90 | 91 | return result; 92 | } 93 | 94 | /// 95 | /// Will texture with solid color 96 | /// 97 | public static Texture2D WithSolidColor(this Texture2D original, Color color) 98 | { 99 | var target = new Texture2D(original.width, original.height); 100 | for (int i = 0; i < target.width; i++) 101 | { 102 | for (int j = 0; j < target.height; j++) 103 | { 104 | target.SetPixel(i, j, color); 105 | } 106 | } 107 | 108 | target.Apply(); 109 | 110 | return target; 111 | } 112 | } 113 | } -------------------------------------------------------------------------------- /Extensions/MyTexture.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9e0ec1dcc4e6fa45a7fedda14460872 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyUI.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43d481a52e319334991a5f2842a957ac 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/MyUnityEventExtensions.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.Annotations; 2 | using UnityEngine.Events; 3 | 4 | namespace MyBox 5 | { 6 | [PublicAPI] 7 | public static class MyUnityEventExtensions 8 | { 9 | /// 10 | /// Adds a listener that executes only once to the UnityEvent. 11 | /// 12 | public static UnityEvent Once(this UnityEvent source, UnityAction action) 13 | { 14 | source.AddListener(WrapperAction); 15 | return source; 16 | 17 | void WrapperAction() 18 | { 19 | source.RemoveListener(WrapperAction); 20 | action(); 21 | } 22 | } 23 | 24 | /// 25 | /// Adds a listener that executes only once to the UnityEvent. 26 | /// 27 | public static UnityEvent Once(this UnityEvent source, UnityAction action) 28 | { 29 | source.AddListener(WrapperAction); 30 | return source; 31 | 32 | void WrapperAction(T p) 33 | { 34 | source.RemoveListener(WrapperAction); 35 | action(p); 36 | } 37 | } 38 | 39 | /// 40 | /// Adds a listener that executes only once to the UnityEvent. 41 | /// 42 | public static UnityEvent Once(this UnityEvent source, UnityAction action) 43 | { 44 | source.AddListener(WrapperAction); 45 | return source; 46 | 47 | void WrapperAction(T0 p0, T1 p1) 48 | { 49 | source.RemoveListener(WrapperAction); 50 | action(p0, p1); 51 | } 52 | } 53 | 54 | /// 55 | /// Adds a listener that executes only once to the UnityEvent. 56 | /// 57 | public static UnityEvent Once(this UnityEvent source, UnityAction action) 58 | { 59 | source.AddListener(WrapperAction); 60 | return source; 61 | 62 | void WrapperAction(T0 p0, T1 p1, T2 p2) 63 | { 64 | source.RemoveListener(WrapperAction); 65 | action(p0, p1, p2); 66 | } 67 | } 68 | 69 | /// 70 | /// Adds a listener that executes only once to the UnityEvent. 71 | /// 72 | public static UnityEvent Once(this UnityEvent source, UnityAction action) 73 | { 74 | source.AddListener(WrapperAction); 75 | return source; 76 | 77 | void WrapperAction(T0 p0, T1 p1, T2 p2, T3 p3) 78 | { 79 | source.RemoveListener(WrapperAction); 80 | action(p0, p1, p2, p3); 81 | } 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /Extensions/MyUnityEventExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: adf49d97edca4d30b9de5ada2a4be258 3 | timeCreated: 1694769869 -------------------------------------------------------------------------------- /Extensions/MyVectors.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 29650b3897e9f0b4fb59619cf59236f7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extensions/TransformShakeExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | using Random = UnityEngine.Random; 6 | 7 | namespace MyBox 8 | { 9 | /// 10 | /// StartShake and StopShake for transform. Use for screenshake on camera transform for instance 11 | /// 12 | public static class TransformShakeExtension 13 | { 14 | /// 15 | /// Coroutine and Initial Position for transform 16 | /// 17 | private static Dictionary> _activeShakingTransforms; 18 | 19 | /// 20 | /// Shake transform, like for screenshake on camera transform 21 | /// 22 | /// Transform to shake 23 | /// Shake time. -1 for infinite shaking 24 | /// Shake amplitude in units 25 | /// Shake time should be affected by Time.timeScale or not 26 | /// Fade bounds to zero to the end of the shake 27 | public static void StartShake(this Transform transform, float time = 0.1f, float shakeBounds = 0.1f, bool useUnscaledTime = true, bool fadeBounds = false) 28 | { 29 | if (_activeShakingTransforms == null) _activeShakingTransforms = new Dictionary>(); 30 | 31 | BreakShakeIfAny(transform); 32 | 33 | var coroutine = TransformShakeCoroutine(transform, time, shakeBounds, useUnscaledTime, fadeBounds).StartCoroutine(); 34 | _activeShakingTransforms.Add(transform, new Tuple(coroutine, transform.position)); 35 | } 36 | 37 | /// 38 | /// Stop Shake for transform, if shaking now 39 | /// 40 | public static void StopShake(this Transform transform) 41 | { 42 | BreakShakeIfAny(transform); 43 | } 44 | 45 | 46 | private static IEnumerator TransformShakeCoroutine(Transform transform, float shakeTime, float bounds, bool useUnscaledTime, bool fadeBounds) 47 | { 48 | Vector3 initialPosition = transform.position; 49 | 50 | float initialBounds = bounds; 51 | float elapsed = 0; 52 | while (shakeTime < 0 || elapsed < shakeTime) 53 | { 54 | yield return null; 55 | 56 | elapsed += useUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime; 57 | float elapsedRate = 1 - elapsed / shakeTime; 58 | 59 | float xShake = Random.value * bounds * 2 - bounds; 60 | float yShake = Random.value * bounds * 2 - bounds; 61 | 62 | Vector3 newPosition = transform.position; 63 | newPosition.x += xShake; 64 | newPosition.y += yShake; 65 | 66 | bounds = fadeBounds ? initialBounds * elapsedRate : initialBounds; 67 | newPosition.x = Mathf.Clamp(newPosition.x, initialPosition.x - bounds, initialPosition.x + bounds); 68 | newPosition.y = Mathf.Clamp(newPosition.y, initialPosition.y - bounds, initialPosition.y + bounds); 69 | 70 | transform.position = newPosition; 71 | } 72 | 73 | transform.position = initialPosition; 74 | _activeShakingTransforms.Remove(transform); 75 | } 76 | 77 | private static void BreakShakeIfAny(Transform transform) 78 | { 79 | if (_activeShakingTransforms == null || !_activeShakingTransforms.ContainsKey(transform)) return; 80 | 81 | var shakeData = _activeShakingTransforms[transform]; 82 | MyCoroutines.StopCoroutine(shakeData.Item1); 83 | transform.position = shakeData.Item2; 84 | 85 | _activeShakingTransforms.Remove(transform); 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /Extensions/TransformShakeExtension.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4cd2d7ed03144d51af5a064aff2d3760 3 | timeCreated: 1569946200 -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Andrew Rumak 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 | -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8e390f5423fbc2143bfe1fa14ef61ff7 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /MyBox.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MyBox", 3 | "rootNamespace": "", 4 | "references": [], 5 | "includePlatforms": [], 6 | "excludePlatforms": [], 7 | "allowUnsafeCode": false, 8 | "overrideReferences": false, 9 | "precompiledReferences": [], 10 | "autoReferenced": true, 11 | "defineConstraints": [], 12 | "versionDefines": [ 13 | { 14 | "name": "com.unity.modules.ai", 15 | "expression": "", 16 | "define": "UNITY_AI_ENABLED" 17 | }, 18 | { 19 | "name": "com.unity.modules.physics2d", 20 | "expression": "", 21 | "define": "UNITY_PHYSICS2D_ENABLED" 22 | }, 23 | { 24 | "name": "com.unity.modules.physics", 25 | "expression": "", 26 | "define": "UNITY_PHYSICS_ENABLED" 27 | }, 28 | { 29 | "name": "com.unity.modules.imageconversion", 30 | "expression": "", 31 | "define": "UNITY_IMAGECONVERSION_ENABLED" 32 | } 33 | ], 34 | "noEngineReferences": false 35 | } -------------------------------------------------------------------------------- /MyBox.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 48c9f6afdac61634db0e0f241c7d4d51 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3e3bf6d12f6d3c64ebb8c67edd5c2a4a 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /TODO.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3a94a7b365e6ee943b4da55544170a3f 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Tools.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f652731d2358e44a9243574824cfa32 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tools/AssetPresetPreprocessor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 44fa70dda88bc6047b3d2ad380cc648a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tools/AssetPresetPreprocessor/AssetPresetPreprocessor.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System.Linq; 3 | using MyBox.EditorTools; 4 | using UnityEditor; 5 | 6 | namespace MyBox.Internal 7 | { 8 | public class AssetPresetPreprocessor : AssetPostprocessor 9 | { 10 | private void OnPreprocessAsset() 11 | { 12 | InitializePreprocessBase(); 13 | if (AssetsPresetPreprocessBase.Instance == null) return; 14 | 15 | foreach (var preset in AssetsPresetPreprocessBase.Instance.Presets) 16 | { 17 | if (preset.Preset == null) continue; 18 | if (!preset.Sample(assetPath)) continue; 19 | if (!preset.Preset.CanBeAppliedTo(assetImporter)) continue; 20 | 21 | context.DependsOnSourceAsset(assetPath); 22 | preset.Preset.ApplyTo(assetImporter, preset.PropertiesToApply); 23 | return; 24 | } 25 | } 26 | 27 | private void InitializePreprocessBase() 28 | { 29 | if (_preprocessBaseChecked) return; 30 | _preprocessBaseChecked = true; 31 | if (AssetsPresetPreprocessBase.Instance != null) return; 32 | 33 | AssetsPresetPreprocessBase.Instance = 34 | MyScriptableObject.LoadAssetsFromResources().FirstOrDefault(); 35 | 36 | if (AssetsPresetPreprocessBase.Instance != null) return; 37 | 38 | AssetsPresetPreprocessBase.Instance = 39 | MyScriptableObject.LoadAssets().SingleOrDefault(); 40 | } 41 | 42 | private static bool _preprocessBaseChecked; 43 | } 44 | } 45 | #endif -------------------------------------------------------------------------------- /Tools/AssetPresetPreprocessor/AssetPresetPreprocessor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 20ac1f2822354281b5c4455cbf4f9db6 3 | timeCreated: 1550748587 -------------------------------------------------------------------------------- /Tools/AssetPresetPreprocessor/AssetsPresetPreprocessBase.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using System.IO; 4 | using UnityEditor; 5 | using UnityEditor.Presets; 6 | using UnityEngine; 7 | 8 | namespace MyBox.Internal 9 | { 10 | public class AssetsPresetPreprocessBase : ScriptableObject 11 | { 12 | public static AssetsPresetPreprocessBase Instance { get; set; } 13 | 14 | public ConditionalPreset[] Presets; 15 | 16 | public string[] ExcludeProperties = { "SpriteBorder", "Pivot", "Alignment" }; 17 | 18 | private void Awake() => Instance = this; 19 | } 20 | 21 | [Serializable] 22 | public class ConditionalPreset 23 | { 24 | public string PathContains; 25 | public string TypeOf; 26 | public string Prefix; 27 | public string Postfix; 28 | 29 | public Preset Preset; 30 | 31 | public string[] PropertiesToApply; 32 | 33 | public bool Sample(string path) 34 | { 35 | var pathSet = !string.IsNullOrEmpty(PathContains); 36 | var typeSet = !string.IsNullOrEmpty(TypeOf); 37 | var prefixSet = !string.IsNullOrEmpty(Prefix); 38 | var postfixSet = !string.IsNullOrEmpty(Postfix); 39 | 40 | if (pathSet && !path.Contains(PathContains)) return false; 41 | 42 | var extension = Path.GetExtension(path); 43 | var filename = Path.GetFileNameWithoutExtension(path); 44 | if (extension == null || filename == null) return false; 45 | 46 | if (typeSet && !extension.Contains(TypeOf)) return false; 47 | 48 | if (prefixSet && !filename.StartsWith(Prefix)) return false; 49 | if (postfixSet && !filename.EndsWith(Postfix)) return false; 50 | 51 | return true; 52 | } 53 | } 54 | } 55 | #endif -------------------------------------------------------------------------------- /Tools/AssetPresetPreprocessor/AssetsPresetPreprocessBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 84c732208449492aa9663cba17a80da4 3 | timeCreated: 1550745571 -------------------------------------------------------------------------------- /Tools/AssetPresetPreprocessor/AssetsPresetPreprocessEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 75e5dfe4a595bba4ca5254e203313a15 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/Features.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: daae734bef9ea954fba8fb03bf90351c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tools/Features/AutoSaveFeature.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | using UnityEditor.SceneManagement; 4 | using UnityEngine.SceneManagement; 5 | 6 | namespace MyBox.Internal 7 | { 8 | [InitializeOnLoad] 9 | public class AutoSaveFeature 10 | { 11 | static AutoSaveFeature() 12 | { 13 | EditorApplication.playModeStateChanged += AutoSaveWhenPlaymodeStarts; 14 | } 15 | 16 | private static void AutoSaveWhenPlaymodeStarts(PlayModeStateChange obj) 17 | { 18 | if (!MyBoxSettings.AutoSaveEnabled) return; 19 | 20 | if (EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying) 21 | { 22 | for (var i = 0; i < SceneManager.sceneCount; i++) 23 | { 24 | var scene = SceneManager.GetSceneAt(i); 25 | if (scene.isDirty) EditorSceneManager.SaveScene(scene); 26 | } 27 | 28 | AssetDatabase.SaveAssets(); 29 | } 30 | } 31 | } 32 | } 33 | #endif -------------------------------------------------------------------------------- /Tools/Features/AutoSaveFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ec5948f15936d6b4fbe4dc7635a7ba69 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/Features/CleanEmptyDirectoriesFeature.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using UnityEditor; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.IO; 8 | 9 | 10 | namespace MyBox.Internal 11 | { 12 | public class CleanEmptyDirectoriesFeature : UnityEditor.AssetModificationProcessor 13 | { 14 | public static string[] OnWillSaveAssets(string[] paths) 15 | { 16 | if (!MyBoxSettings.CleanEmptyDirectoriesFeature) return paths; 17 | 18 | // Sometimes somehow SaveAssets caused with null path; 19 | // Prefab creation enforces SaveAsset and this may cause unwanted dir cleanup; 20 | // Folder creation also causes SaveAsset so it's not possible to create folders; 21 | if (paths.Length == 1) 22 | { 23 | bool isEmpty = paths[0] == null; 24 | bool isPrefab = paths[0].EndsWith(".prefab"); 25 | bool isFolder = paths[0].EndsWith(".meta"); 26 | 27 | if (isEmpty || isPrefab || isFolder) return paths; 28 | } 29 | 30 | List emptyDirectories = GetEmptyDirectories(); 31 | foreach (var emptyDirectory in emptyDirectories) DeleteEmptyDirectory(emptyDirectory); 32 | 33 | return paths; 34 | } 35 | 36 | private static List GetEmptyDirectories() 37 | { 38 | var emptyDirectories = new List(); 39 | var assetDirectory = new DirectoryInfo(Application.dataPath); 40 | 41 | WalkDirectoryTree(assetDirectory, (directoryInfo, areSubDirectoriesEmpty) => 42 | { 43 | bool isEmpty = areSubDirectoriesEmpty && DirectoryIsEmpty(directoryInfo); 44 | if (isEmpty) emptyDirectories.Add(directoryInfo); 45 | return isEmpty; 46 | }); 47 | 48 | return emptyDirectories; 49 | } 50 | 51 | private static bool DirectoryIsEmpty(DirectoryInfo dirInfo) 52 | { 53 | FileInfo[] files = null; 54 | 55 | try 56 | { 57 | files = dirInfo.GetFiles("*.*"); 58 | files = files.Where(x => !x.Name.EndsWith(".meta")).ToArray(); 59 | } 60 | catch (Exception ex) 61 | { 62 | Debug.LogException(ex); 63 | } 64 | 65 | return files == null || files.Length == 0; 66 | } 67 | 68 | 69 | private static void DeleteEmptyDirectory(DirectoryInfo emptyDirectory) 70 | { 71 | var relativePath = GetRelativePath(emptyDirectory.FullName, Directory.GetCurrentDirectory()); 72 | AssetDatabase.MoveAssetToTrash(relativePath); 73 | Debug.Log("Empty directory removed at: " + emptyDirectory.FullName); 74 | } 75 | 76 | 77 | // return: Is this directory empty? 78 | private delegate bool IsEmptyDirectory(DirectoryInfo dirInfo, bool areSubDirectoriesEmpty); 79 | 80 | // return: Is this directory empty? 81 | private static bool WalkDirectoryTree(DirectoryInfo root, IsEmptyDirectory pred) 82 | { 83 | DirectoryInfo[] subDirectories = root.GetDirectories(); 84 | 85 | bool areSubDirsEmpty = true; 86 | foreach (DirectoryInfo dirInfo in subDirectories) 87 | { 88 | if (!WalkDirectoryTree(dirInfo, pred)) 89 | areSubDirsEmpty = false; 90 | } 91 | 92 | bool isRootEmpty = pred(root, areSubDirsEmpty); 93 | return isRootEmpty; 94 | } 95 | 96 | private static string GetRelativePath(string file, string folder) 97 | { 98 | Uri pathUri = new Uri(file); 99 | // Folders must end in a slash 100 | if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString())) 101 | folder += Path.DirectorySeparatorChar; 102 | 103 | Uri folderUri = new Uri(folder); 104 | return Uri.UnescapeDataString(folderUri.MakeRelativeUri(pathUri).ToString().Replace('/', Path.DirectorySeparatorChar)); 105 | } 106 | } 107 | } 108 | #endif -------------------------------------------------------------------------------- /Tools/Features/CleanEmptyDirectoriesFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ddb889712ded3a048a568870fa1331a8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/Features/CollapsableEventDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: df244a7360a14c7aa31e54bd3b4763f3 3 | timeCreated: 1579185074 -------------------------------------------------------------------------------- /Tools/Features/IPrepareFeature.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MyBox 4 | { 5 | /// 6 | /// Prepare() called on every MonoBehaviour by IPrepareFeature class. If Prepare() returns true, parent scene will be marked dirty 7 | /// 8 | public interface IPrepare 9 | { 10 | bool Prepare(); 11 | } 12 | } 13 | 14 | #if UNITY_EDITOR 15 | namespace MyBox.EditorTools 16 | { 17 | using System.Collections.Generic; 18 | using System.Linq; 19 | using UnityEngine; 20 | using UnityEditor; 21 | using UnityEditor.SceneManagement; 22 | using UnityEngine.SceneManagement; 23 | using MyBox.Internal; 24 | 25 | [InitializeOnLoad] 26 | public class IPrepareFeature 27 | { 28 | public static Action OnPrepareBefore; 29 | public static Action OnPrepare; 30 | public static Action OnPrepareAfter; 31 | 32 | static IPrepareFeature() 33 | { 34 | MyEditorEvents.BeforePlaymode += PrepareOnPlay; 35 | } 36 | 37 | private static void PrepareOnPlay() 38 | { 39 | OnPrepareBefore?.Invoke(); 40 | OnPrepare?.Invoke(); 41 | OnPrepareAfter?.Invoke(); 42 | 43 | if (MyBoxSettings.PrepareOnPlaymode) RunIPrepare(); 44 | } 45 | 46 | /// 47 | /// Calls Prepare() on any MonoBehaviour with IPrepare interface. If Prepare() returns true, parent scene will be marked dirty 48 | /// 49 | public static void RunIPrepare() 50 | { 51 | var toPrepare = MyExtensions.FindObjectsOfInterfaceAsComponents(); 52 | 53 | HashSet modifiedScenes = null; 54 | foreach (var prepare in toPrepare) 55 | { 56 | bool changed = prepare.Interface.Prepare(); 57 | 58 | if (changed && prepare.Component != null) 59 | { 60 | if (modifiedScenes == null) modifiedScenes = new HashSet(); 61 | modifiedScenes.Add(prepare.Component.gameObject.scene); 62 | 63 | EditorUtility.SetDirty(prepare.Component); 64 | PrefabUtility.RecordPrefabInstancePropertyModifications(prepare.Component); 65 | Debug.Log(prepare.Component.name + "." + prepare.Component.GetType().Name + ": Changed on Prepare", prepare.Component); 66 | } 67 | } 68 | 69 | if (modifiedScenes != null) EditorSceneManager.SaveScenes(modifiedScenes.ToArray()); 70 | } 71 | } 72 | } 73 | #endif -------------------------------------------------------------------------------- /Tools/Features/IPrepareFeature.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cb4dba700ba73c64e93b8c51cfdf5ad2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/Features/MoveComponentInInspectorMenuItems.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace MyBox.Internal 6 | { 7 | public static class MoveComponentInInspectorMenuItems 8 | { 9 | [MenuItem("CONTEXT/Component/Move To Top", priority = 501)] 10 | public static void MoveComponentToTop(MenuCommand item) => 11 | MyComponentUtility.MoveComponentInspectorToTop((Component)item.context); 12 | 13 | [MenuItem("CONTEXT/Component/Move To Bottom", priority = 502)] 14 | public static void MoveComponentToBottom(MenuCommand item) => 15 | MyComponentUtility.MoveComponentInspectorToBottom((Component)item.context); 16 | } 17 | } 18 | #endif -------------------------------------------------------------------------------- /Tools/Features/MoveComponentInInspectorMenuItems.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5494c9ba72a4cf2afeca510ea35e73e 3 | timeCreated: 1705652153 -------------------------------------------------------------------------------- /Tools/Features/SceneViewBookmarkHotkeys.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a61c807ff114572a79e0fd687d2ee30 3 | timeCreated: 1552384509 -------------------------------------------------------------------------------- /Tools/Features/SelectionHistoryHotkeys.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Author: Matthew Miner 3 | // https://github.com/mminer/selection-history-navigator/blob/master/SelectionHistoryNavigator.cs 4 | // Date: 22/04/2018 5 | // ---------------------------------------------------------------------------- 6 | 7 | #if UNITY_EDITOR 8 | using System.Collections.Generic; 9 | using UnityEditor; 10 | using UnityEngine; 11 | 12 | namespace MyBox.Internal 13 | { 14 | [InitializeOnLoad] 15 | public static class SelectionHistoryHotkeys 16 | { 17 | /// 18 | /// Adds Back and Forward items to the Edit > Selection menu to navigate between Hierarchy and Project pane selections. 19 | /// 20 | private static Object _activeSelection; 21 | 22 | private static bool _ignoreNextSelectionChangedEvent; 23 | private static readonly Stack NextSelections = new Stack(); 24 | private static readonly Stack PreviousSelections = new Stack(); 25 | 26 | static SelectionHistoryHotkeys() 27 | { 28 | Selection.selectionChanged += SelectionChangedHandler; 29 | } 30 | 31 | private static void SelectionChangedHandler() 32 | { 33 | if (_ignoreNextSelectionChangedEvent) 34 | { 35 | _ignoreNextSelectionChangedEvent = false; 36 | return; 37 | } 38 | 39 | if (_activeSelection != null) PreviousSelections.Push(_activeSelection); 40 | 41 | _activeSelection = Selection.activeObject; 42 | NextSelections.Clear(); 43 | } 44 | 45 | 46 | private const string BackMenuLabel = "Tools/MyBox/Back In Selection History %#["; 47 | private const string ForwardMenuLabel = "Tools/MyBox/Forward In Selection History %#]"; 48 | 49 | [MenuItem(BackMenuLabel)] 50 | private static void Back() 51 | { 52 | if (_activeSelection != null) NextSelections.Push(_activeSelection); 53 | 54 | Selection.activeObject = PreviousSelections.Pop(); 55 | _activeSelection = Selection.activeObject; 56 | _ignoreNextSelectionChangedEvent = true; 57 | } 58 | 59 | [MenuItem(ForwardMenuLabel)] 60 | private static void Forward() 61 | { 62 | if (_activeSelection != null) PreviousSelections.Push(_activeSelection); 63 | 64 | Selection.activeObject = NextSelections.Pop(); 65 | _activeSelection = Selection.activeObject; 66 | _ignoreNextSelectionChangedEvent = true; 67 | } 68 | 69 | [MenuItem(BackMenuLabel, true)] 70 | static bool ValidateBack() 71 | { 72 | return PreviousSelections.Count > 0; 73 | } 74 | 75 | [MenuItem(ForwardMenuLabel, true)] 76 | static bool ValidateForward() 77 | { 78 | return NextSelections.Count > 0; 79 | } 80 | } 81 | } 82 | #endif -------------------------------------------------------------------------------- /Tools/Features/SelectionHistoryHotkeys.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6ec1e19b0f91485aab3602dbace52692 3 | timeCreated: 1552383273 -------------------------------------------------------------------------------- /Tools/Features/ToggleInspectorDebugHotkey.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using System.Reflection; 4 | using UnityEditor; 5 | using UnityEngine; 6 | using Object = UnityEngine.Object; 7 | 8 | namespace MyBox.Internal 9 | { 10 | public static class ToggleInspectorDebugHotkey 11 | { 12 | [MenuItem("Tools/MyBox/Toggle Console Debug &d")] 13 | static void ToggleInspectorDebug() 14 | { 15 | Type inspectorWindowType = Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.InspectorWindow"); 16 | 17 | if (_inspectorWindow == null) 18 | { 19 | Object[] findObjectsOfTypeAll = Resources.FindObjectsOfTypeAll(inspectorWindowType); 20 | _inspectorWindow = (EditorWindow) findObjectsOfTypeAll[0]; 21 | } 22 | 23 | if (_inspectorWindow != null && _inspectorWindow.GetType().Name == "InspectorWindow") 24 | { 25 | FieldInfo inspectorMode = inspectorWindowType.GetField( 26 | "m_InspectorMode", 27 | BindingFlags.NonPublic | BindingFlags.Instance); 28 | MethodInfo setModeMethod = inspectorWindowType.GetMethod( 29 | "SetMode", 30 | BindingFlags.NonPublic | BindingFlags.Instance); 31 | 32 | if (inspectorMode == null || setModeMethod == null) return; 33 | 34 | InspectorMode mode = (InspectorMode)inspectorMode.GetValue(_inspectorWindow); 35 | mode = mode == InspectorMode.Normal ? InspectorMode.Debug : InspectorMode.Normal; 36 | 37 | setModeMethod.Invoke(_inspectorWindow, new object[] { mode }); 38 | _inspectorWindow.Repaint(); 39 | } 40 | } 41 | 42 | private static EditorWindow _inspectorWindow; 43 | } 44 | } 45 | #endif -------------------------------------------------------------------------------- /Tools/Features/ToggleInspectorDebugHotkey.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4eaaff8d726d485dba777956c339641a 3 | timeCreated: 1666252388 -------------------------------------------------------------------------------- /Tools/Features/ToggleInspectorLockHotkey.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | // ---------------------------------------------------------------------------- 3 | // Author: Abomb 4 | // https://forum.unity.com/threads/shortcut-key-for-lock-inspector.95815/#post-1056603 5 | // Date: 09/10/2012 6 | // ---------------------------------------------------------------------------- 7 | 8 | using System; 9 | using System.Reflection; 10 | using UnityEditor; 11 | using UnityEngine; 12 | using Object = UnityEngine.Object; 13 | 14 | namespace MyBox.Internal 15 | { 16 | public static class ToggleInspectorLockHotkey 17 | { 18 | [MenuItem("Tools/MyBox/Toggle Inspector Lock &q")] 19 | static void ToggleInspectorLock() 20 | { 21 | Type inspectorWindowType = Assembly.GetAssembly(typeof(Editor)).GetType("UnityEditor.InspectorWindow"); 22 | 23 | if (_inspectorWindow == null) 24 | { 25 | Object[] findObjectsOfTypeAll = Resources.FindObjectsOfTypeAll(inspectorWindowType); 26 | _inspectorWindow = (EditorWindow) findObjectsOfTypeAll[0]; 27 | } 28 | 29 | if (_inspectorWindow != null && _inspectorWindow.GetType().Name == "InspectorWindow") 30 | { 31 | PropertyInfo isLockedPropertyInfo = inspectorWindowType.GetProperty("isLocked"); 32 | if (isLockedPropertyInfo == null) return; 33 | 34 | bool value = (bool) isLockedPropertyInfo.GetValue(_inspectorWindow, null); 35 | isLockedPropertyInfo.SetValue(_inspectorWindow, !value, null); 36 | 37 | _inspectorWindow.Repaint(); 38 | } 39 | } 40 | 41 | private static EditorWindow _inspectorWindow; 42 | } 43 | } 44 | #endif 45 | -------------------------------------------------------------------------------- /Tools/Features/ToggleInspectorLockHotkey.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5abd87bf044729049b178cd2f640db97 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/ImageStringConverter.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b84cc01ef992446fa625eaa096df0e9b 3 | timeCreated: 1550247432 -------------------------------------------------------------------------------- /Tools/ImageStringConverter/ImageStringConverter.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_IMAGECONVERSION_ENABLED 2 | using System; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | public static class ImageStringConverter 8 | { 9 | /// 10 | /// Use "Tools/MyBox/String Image Converter" to get string image representation 11 | /// 12 | public static Texture2D ImageFromString(string source, int width, int height) 13 | { 14 | var bytes = Convert.FromBase64String(source); 15 | var texture = new Texture2D(width, height); 16 | texture.LoadImage(bytes); 17 | return texture; 18 | } 19 | } 20 | } 21 | #endif -------------------------------------------------------------------------------- /Tools/ImageStringConverter/ImageStringConverter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cc6dd669bedc4c9692041cf335dfa495 3 | timeCreated: 1550247474 -------------------------------------------------------------------------------- /Tools/ImageStringConverter/ImageToStringConverterEditor.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_IMAGECONVERSION_ENABLED 2 | #if UNITY_EDITOR 3 | using System; 4 | using System.IO; 5 | using MyBox.EditorTools; 6 | using UnityEditor; 7 | using UnityEngine; 8 | 9 | namespace MyBox.Internal 10 | { 11 | /// 12 | /// This tool allows to save image as a string and load image back from that string. 13 | /// It allows to store simple textures as const strings right in script files. 14 | /// I suggest to use tinypng.com before conversion! 15 | /// 16 | public class ImageToStringConverterEditor : EditorWindow 17 | { 18 | [MenuItem("Tools/MyBox/Image To String Converter", false, 50)] 19 | private static void CreateWindow() 20 | { 21 | var window = GetWindow(false, "Image To String Converter"); 22 | window.minSize = new Vector2(400, 300); 23 | window.maxSize = new Vector2(400, 800); 24 | window.Show(); 25 | } 26 | 27 | private string _representation; 28 | private int _width = 64; 29 | private int _height = 64; 30 | 31 | private Texture2D _texture; 32 | 33 | private void OnGUI() 34 | { 35 | EditorGUILayout.Space(); 36 | EditorGUILayout.HelpBox("1: Drag any image to \"Drag Texture\" field below \n" + 37 | " (from any place, not just an assets folder)\n" + 38 | "* it's better to optimize it before, try tinypng.com\n" + 39 | "* image size is very important too, big pics will cost a lot!\n" + 40 | "2: Store the result as a const string in your sources\n" + 41 | "3: Convert the string into image during runtime with method \n" + 42 | " \"ImageStringConverter.ImageFromString\"", MessageType.Info); 43 | EditorGUILayout.Space(); 44 | 45 | var selected = MyGUI.DropAreaPaths("Drag Texture", 60); 46 | GUI.enabled = false; 47 | EditorGUILayout.TextArea(_representation); 48 | GUI.enabled = true; 49 | 50 | EditorGUILayout.Space(); 51 | using (new EditorGUILayout.HorizontalScope()) 52 | { 53 | EditorGUILayout.LabelField("Preview Width: ", GUILayout.Width(120)); 54 | _width = EditorGUILayout.IntField(GUIContent.none, _width, GUILayout.Width(60)); 55 | EditorGUILayout.LabelField("Preview Height: ", GUILayout.Width(120)); 56 | _height = EditorGUILayout.IntField(GUIContent.none, _height, GUILayout.Width(60)); 57 | } 58 | if (_texture != null) EditorGUILayout.LabelField(new GUIContent(_texture), GUILayout.Width(_width), GUILayout.Height(_height)); 59 | 60 | if (selected == null || selected.Length == 0) return; 61 | 62 | string content = Convert.ToBase64String(File.ReadAllBytes(selected[0])); 63 | _representation = content; 64 | 65 | MyEditor.CopyToClipboard(_representation); 66 | ShowNotification(new GUIContent(selected[0] + "\nCopied to Clipboard as string")); 67 | 68 | _texture = ImageStringConverter.ImageFromString(_representation, _width, _height); 69 | 70 | } 71 | } 72 | } 73 | #endif 74 | #endif -------------------------------------------------------------------------------- /Tools/ImageStringConverter/ImageToStringConverterEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f8a2783431c4464bf7643f078e3e716 3 | timeCreated: 1541488681 -------------------------------------------------------------------------------- /Tools/Internal.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9edfed511fd35584aa76d99f420d8ffb 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Tools/Internal/ConditionalData.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Reflection; 4 | using UnityEngine; 5 | 6 | namespace MyBox.Internal 7 | { 8 | public class ConditionalData 9 | { 10 | public bool IsSet => _fieldToCheck.NotNullOrEmpty() || _fieldsToCheckMultiple.NotNullOrEmpty() || _predicateMethod.NotNullOrEmpty(); 11 | 12 | private readonly string _fieldToCheck; 13 | private readonly bool _inverse; 14 | private readonly string[] _compareValues; 15 | 16 | private readonly string[] _fieldsToCheckMultiple; 17 | private readonly bool[] _inverseMultiple; 18 | private readonly string[] _compareValuesMultiple; 19 | 20 | private readonly string _predicateMethod; 21 | 22 | public ConditionalData(string fieldToCheck, bool inverse = false, params object[] compareValues) 23 | => (_fieldToCheck, _inverse, _compareValues) = 24 | (fieldToCheck, inverse, compareValues.Select(c => c.ToString().ToUpper()).ToArray()); 25 | 26 | public ConditionalData(string[] fieldToCheck, bool[] inverse = null, params object[] compare) => 27 | (_fieldsToCheckMultiple, _inverseMultiple, _compareValuesMultiple) = 28 | (fieldToCheck, inverse, compare.Select(c => c.ToString().ToUpper()).ToArray()); 29 | 30 | public ConditionalData(params string[] fieldToCheck) => _fieldsToCheckMultiple = fieldToCheck; 31 | 32 | // ReSharper disable once UnusedParameter.Local 33 | public ConditionalData(bool useMethod, string methodName, bool inverse = false) 34 | => (_predicateMethod, _inverse) = (methodName, inverse); 35 | 36 | 37 | #if UNITY_EDITOR 38 | /// 39 | /// Iterate over Field Conditions 40 | /// 41 | public IEnumerator<(string Field, bool Inverse, string[] CompareAgainst)> GetEnumerator() 42 | { 43 | if (_fieldToCheck.NotNullOrEmpty()) yield return (_fieldToCheck, _inverse, _compareValues); 44 | if (_fieldsToCheckMultiple.NotNullOrEmpty()) 45 | { 46 | for (var i = 0; i < _fieldsToCheckMultiple.Length; i++) 47 | { 48 | var field = _fieldsToCheckMultiple[i]; 49 | bool withInverseValue = _inverseMultiple != null && _inverseMultiple.Length - 1 >= i; 50 | bool withCompareValue = _compareValuesMultiple != null && _compareValuesMultiple.Length - 1 >= i; 51 | var inverse = withInverseValue && _inverseMultiple[i]; 52 | var compare = withCompareValue ? new[] { _compareValuesMultiple[i] } : null; 53 | 54 | yield return (field, inverse, compare); 55 | } 56 | } 57 | } 58 | 59 | /// 60 | /// Call and check Method Condition, if any 61 | /// 62 | public bool IsMethodConditionMatch(object owner) 63 | { 64 | if (_predicateMethod.IsNullOrEmpty()) return true; 65 | 66 | var predicateMethod = GetMethodCondition(owner); 67 | if (predicateMethod == null) return true; 68 | 69 | bool match = (bool)predicateMethod.Invoke(owner, null); 70 | if (_inverse) match = !match; 71 | return match; 72 | } 73 | 74 | 75 | private MethodInfo GetMethodCondition(object owner) 76 | { 77 | if (_predicateMethod.IsNullOrEmpty()) return null; 78 | if (_initializedMethodInfo) return _cachedMethodInfo; 79 | _initializedMethodInfo = true; 80 | 81 | var ownerType = owner.GetType(); 82 | var bindings = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; 83 | var method = ownerType.GetMethods(bindings).SingleOrDefault(m => m.Name == _predicateMethod); 84 | 85 | if (method == null || method.ReturnType != typeof(bool)) 86 | { 87 | ConditionalUtility.LogMethodNotFound((Object)owner, _predicateMethod); 88 | _cachedMethodInfo = null; 89 | } 90 | else _cachedMethodInfo = method; 91 | 92 | return _cachedMethodInfo; 93 | } 94 | 95 | private MethodInfo _cachedMethodInfo; 96 | private bool _initializedMethodInfo; 97 | #endif 98 | } 99 | } -------------------------------------------------------------------------------- /Tools/Internal/ConditionalData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6dbc9d6ec862469faa39d1d6702d7540 3 | timeCreated: 1654504912 -------------------------------------------------------------------------------- /Tools/Internal/ConditionalUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 645be1cae2c0450b825b035ea9165d49 3 | timeCreated: 1654502905 -------------------------------------------------------------------------------- /Tools/Internal/CustomDrawerUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2bf1323b9b8d4f0ca805e0d2a409dd07 3 | timeCreated: 1654673209 -------------------------------------------------------------------------------- /Tools/Internal/MyBoxInternalPath.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using MyBox.EditorTools; 3 | using UnityEngine; 4 | using System.IO; 5 | 6 | namespace MyBox.Internal 7 | { 8 | /// 9 | /// SO is needed to determine the path to this script. 10 | /// Thereby it's used to get relative path to MyBox 11 | /// 12 | public class MyBoxInternalPath : ScriptableObject 13 | { 14 | /// 15 | /// Absolute path to MyBox folder 16 | /// 17 | public static DirectoryInfo MyBoxDirectory 18 | { 19 | get 20 | { 21 | if (_directoryChecked) return _myBoxDirectory; 22 | 23 | var internalPath = MyEditor.GetScriptAssetPath(Instance); 24 | var scriptDirectory = new DirectoryInfo(internalPath); 25 | 26 | // Script is in MyBox/Tools/Internal so we need to get dir two steps up in hierarchy 27 | if (scriptDirectory.Parent == null || scriptDirectory.Parent.Parent == null) 28 | { 29 | _directoryChecked = true; 30 | return null; 31 | } 32 | 33 | _myBoxDirectory = scriptDirectory.Parent.Parent; 34 | _directoryChecked = true; 35 | return _myBoxDirectory; 36 | } 37 | } 38 | 39 | private static DirectoryInfo _myBoxDirectory; 40 | private static bool _directoryChecked; 41 | 42 | private static MyBoxInternalPath Instance 43 | { 44 | get 45 | { 46 | if (_instance != null) return _instance; 47 | return _instance = CreateInstance(); 48 | } 49 | } 50 | 51 | private static MyBoxInternalPath _instance; 52 | } 53 | } 54 | #endif -------------------------------------------------------------------------------- /Tools/Internal/MyBoxInternalPath.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd4c04bc7f7240958b670871b7e79094 3 | timeCreated: 1566072116 -------------------------------------------------------------------------------- /Tools/Internal/MyBoxMenuItems.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | 4 | namespace MyBox.Internal 5 | { 6 | public static class MyBoxMenuItems 7 | { 8 | private const string Base = "Tools/MyBox/"; 9 | private const string AutoSaveMenuItemKey = Base + "AutoSave on play"; 10 | private const string CleanupEmptyDirectoriesMenuItemKey = Base + "Clear empty directories On Save"; 11 | private const string PrepareMenuItemKey = Base + "Run Prepare on play"; 12 | private const string CheckForUpdatesKey = Base + "Check for updates on start"; 13 | 14 | 15 | #region AutoSave 16 | 17 | [MenuItem(AutoSaveMenuItemKey, priority = 100)] 18 | private static void AutoSaveMenuItem() 19 | => MyBoxSettings.AutoSaveEnabled = !MyBoxSettings.AutoSaveEnabled; 20 | 21 | [MenuItem(AutoSaveMenuItemKey, true)] 22 | private static bool AutoSaveMenuItemValidation() 23 | { 24 | Menu.SetChecked(AutoSaveMenuItemKey, MyBoxSettings.AutoSaveEnabled); 25 | return true; 26 | } 27 | 28 | #endregion 29 | 30 | 31 | #region CleanupEmptyDirectories 32 | 33 | [MenuItem(CleanupEmptyDirectoriesMenuItemKey, priority = 100)] 34 | private static void CleanupEmptyDirectoriesMenuItem() 35 | => MyBoxSettings.CleanEmptyDirectoriesFeature = !MyBoxSettings.CleanEmptyDirectoriesFeature; 36 | 37 | [MenuItem(CleanupEmptyDirectoriesMenuItemKey, true)] 38 | private static bool CleanupEmptyDirectoriesMenuItemValidation() 39 | { 40 | Menu.SetChecked(CleanupEmptyDirectoriesMenuItemKey, MyBoxSettings.CleanEmptyDirectoriesFeature); 41 | return true; 42 | } 43 | 44 | #endregion 45 | 46 | 47 | #region Prepare 48 | 49 | [MenuItem(PrepareMenuItemKey, priority = 100)] 50 | private static void PrepareMenuItem() 51 | => MyBoxSettings.PrepareOnPlaymode = !MyBoxSettings.PrepareOnPlaymode; 52 | 53 | [MenuItem(PrepareMenuItemKey, true)] 54 | private static bool PrepareMenuItemValidation() 55 | { 56 | Menu.SetChecked(PrepareMenuItemKey, MyBoxSettings.PrepareOnPlaymode); 57 | return true; 58 | } 59 | 60 | #endregion 61 | 62 | 63 | #region Check For Updates 64 | 65 | [MenuItem(CheckForUpdatesKey, priority = 100)] 66 | private static void CheckForUpdatesMenuItem() 67 | => MyBoxSettings.CheckForUpdates = !MyBoxSettings.CheckForUpdates; 68 | 69 | [MenuItem(CheckForUpdatesKey, true)] 70 | private static bool CheckForUpdatesMenuItemValidation() 71 | { 72 | Menu.SetChecked(CheckForUpdatesKey, MyBoxSettings.CheckForUpdates); 73 | return true; 74 | } 75 | 76 | #endregion 77 | } 78 | } 79 | #endif -------------------------------------------------------------------------------- /Tools/Internal/MyBoxMenuItems.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d5066814d8294782a0d959988feb2684 3 | timeCreated: 1564492977 -------------------------------------------------------------------------------- /Tools/Internal/MyBoxSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6d9574cd9fd624c47b731e243b62972c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/Internal/MyBoxUtilities.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2625afd64fa74f3c99c1353ee281bf30 3 | timeCreated: 1573568630 -------------------------------------------------------------------------------- /Tools/Internal/MyBoxVersion.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | 4 | namespace MyBox.Internal 5 | { 6 | [Serializable] 7 | public class MyBoxVersion 8 | { 9 | public string Major; 10 | public string Minor; 11 | public string Patch; 12 | 13 | public string AsSting; 14 | 15 | /// NUM.NUM.NUM format 16 | public MyBoxVersion(string version) 17 | { 18 | AsSting = version; 19 | var v = version.Split('.'); 20 | Major = v[0]; 21 | Minor = v[1]; 22 | Patch = v[2]; 23 | } 24 | 25 | /// 26 | /// Major & Minor versions match, skip patch releases 27 | /// 28 | public bool BaseVersionMatch(MyBoxVersion version) 29 | { 30 | return Major == version.Major && Minor == version.Minor; 31 | } 32 | 33 | public bool VersionsMatch(MyBoxVersion version) 34 | { 35 | return BaseVersionMatch(version) && Patch == version.Patch; 36 | } 37 | } 38 | } 39 | #endif -------------------------------------------------------------------------------- /Tools/Internal/MyBoxVersion.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7c2b0cdefbd748bf921af402c44e1b67 3 | timeCreated: 1573637452 -------------------------------------------------------------------------------- /Tools/Internal/MyBoxWindow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 635635a0d91a4439a0ab3bf7ae21597a 3 | timeCreated: 1565678068 -------------------------------------------------------------------------------- /Tools/Internal/SearchablePopup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d1a78b82e1f34ca981f57196e3d9a6da 3 | timeCreated: 1655377300 -------------------------------------------------------------------------------- /Tools/Internal/UnityObjectEditor.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR && !MYBOX_DISABLE_INSPECTOR_OVERRIDE && !ODIN_INSPECTOR 2 | namespace MyBox.Internal 3 | { 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | [CustomEditor(typeof(Object), true), CanEditMultipleObjects] 8 | public class UnityObjectEditor : Editor 9 | { 10 | private FoldoutAttributeHandler _foldout; 11 | private ButtonMethodHandler _buttonMethod; 12 | 13 | private void OnEnable() 14 | { 15 | if (target == null) return; 16 | 17 | _foldout = new FoldoutAttributeHandler(target, serializedObject); 18 | _buttonMethod = new ButtonMethodHandler(target); 19 | } 20 | 21 | private void OnDisable() 22 | { 23 | _foldout?.OnDisable(); 24 | } 25 | 26 | public override void OnInspectorGUI() 27 | { 28 | _buttonMethod?.OnBeforeInspectorGUI(); 29 | 30 | if (_foldout != null) 31 | { 32 | _foldout.Update(); 33 | if (!_foldout.OverrideInspector) base.OnInspectorGUI(); 34 | else _foldout.OnInspectorGUI(); 35 | } 36 | 37 | _buttonMethod?.OnAfterInspectorGUI(); 38 | } 39 | } 40 | } 41 | #endif -------------------------------------------------------------------------------- /Tools/Internal/UnityObjectEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e53afb9413554e64be65650721f4bb12 3 | timeCreated: 1576668537 -------------------------------------------------------------------------------- /Tools/MyEditorEvents.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d01553cfc6df446786243bccf35573da 3 | timeCreated: 1554719048 -------------------------------------------------------------------------------- /Tools/MyEditorEventsBehaviorHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace MyBox.Internal 5 | { 6 | [ExecuteInEditMode] 7 | public class MyEditorEventsBehaviorHandler : MonoBehaviour 8 | { 9 | public static void InitializeInstance() 10 | { 11 | if (_instance != null) return; 12 | _instance = FindAnyObjectByType(); 13 | if (_instance != null) return; 14 | 15 | var handlerGameObject = new GameObject("MyEditorEventsBehaviorHandler"); 16 | _instance = handlerGameObject.AddComponent(); 17 | if (Application.isPlaying) DontDestroyOnLoad(_instance.gameObject); 18 | handlerGameObject.hideFlags = HideFlags.HideAndDontSave; 19 | } 20 | private static MyEditorEventsBehaviorHandler _instance; 21 | 22 | public static event Action OnGUIEvent; 23 | public static event Action OnUpdate; 24 | 25 | private void OnGUI() => OnGUIEvent?.Invoke(); 26 | private void Update() => OnUpdate?.Invoke(); 27 | } 28 | } -------------------------------------------------------------------------------- /Tools/MyEditorEventsBehaviorHandler.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a9281b1e4e848b1badf486e4c120ff5 3 | timeCreated: 1727780365 -------------------------------------------------------------------------------- /Tools/MySceneBundle.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fec9f9b806264926bde41b66bc712e03 3 | timeCreated: 1566998981 -------------------------------------------------------------------------------- /Tools/TimeTest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9f5c1cabde11a7244b34e3753717c5a0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/Undone.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f05e7d49c544ee4840212b56cdb65bb 3 | timeCreated: 1550246901 -------------------------------------------------------------------------------- /Tools/Undone/AnimationCreator.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | using UnityEditor.Animations; 4 | using UnityEngine; 5 | 6 | namespace MyBox.Internal 7 | { 8 | public class AnimationCreator 9 | { 10 | /// 11 | /// Create .controller asset at path and assign with targetObject.Animator 12 | /// 13 | /// Object to add Animation Controller 14 | /// Path to save controller 15 | /// Create .anim assets with given names and assign to .controller. 16 | /// Names with + on end will generate as looping clips 17 | public static void CreateAnimationControllerAsset(GameObject targetObject, string path, params string[] clips) 18 | { 19 | var animator = targetObject.GetComponent(); 20 | if (animator == null) animator = targetObject.AddComponent(); 21 | if (animator.runtimeAnimatorController != null) 22 | { 23 | Debug.LogWarning("Target already contains Animator with Controller"); 24 | return; 25 | } 26 | 27 | var controllerPath = AssetDatabase.GenerateUniqueAssetPath(path + "Animation.controller"); 28 | var controller = AnimatorController.CreateAnimatorControllerAtPath(controllerPath); 29 | 30 | if (clips != null) 31 | { 32 | for (var i = 0; i < clips.Length; i++) 33 | { 34 | var clipName = clips[i]; 35 | var clip = new AnimationClip(); 36 | 37 | if (clipName.EndsWith("+")) 38 | { 39 | var clipSO = new SerializedObject(clip); 40 | var clipSettingsProp = clipSO.FindProperty("m_AnimationClipSettings"); 41 | var loopProp = clipSettingsProp.FindPropertyRelative("m_LoopTime"); 42 | 43 | loopProp.boolValue = true; 44 | clipSO.ApplyModifiedProperties(); 45 | 46 | clipName = clipName.TrimEnd('+'); 47 | } 48 | 49 | var clipPath = AssetDatabase.GenerateUniqueAssetPath(path + clipName + ".anim"); 50 | AssetDatabase.CreateAsset(clip, clipPath); 51 | 52 | var motion = controller.AddMotion(clip); 53 | motion.name = clipName; 54 | 55 | EditorUtility.SetDirty(clip); 56 | } 57 | } 58 | 59 | animator.runtimeAnimatorController = controller; 60 | 61 | EditorUtility.SetDirty(controller); 62 | EditorUtility.SetDirty(targetObject); 63 | } 64 | } 65 | } 66 | #endif -------------------------------------------------------------------------------- /Tools/Undone/AnimationCreator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e774eae9d01a483ca895a35b92ac00e4 3 | timeCreated: 1535972539 -------------------------------------------------------------------------------- /Tools/Undone/EmbeddedAnimationCreator.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using MyBox.EditorTools; 3 | using UnityEngine; 4 | using UnityEditor; 5 | using UnityEditor.Animations; 6 | 7 | namespace MyBox.Internal 8 | { 9 | public class EmbeddedAnimationCreator : EditorWindow 10 | { 11 | //[MenuItem("Tools/MyBox/Embedded Animation Creator", false, 50)] 12 | private static void CreateWindow() 13 | { 14 | _instance = GetWindow(); 15 | _instance.Show(); 16 | } 17 | 18 | private static EmbeddedAnimationCreator _instance; 19 | private AnimatorController _currentAnimator; 20 | 21 | private string _newClipName = string.Empty; 22 | 23 | public void OnGUI() 24 | { 25 | EditorGUILayout.Space(); 26 | 27 | if (_currentAnimator == null) 28 | { 29 | EditorGUILayout.HelpBox("Select Animation Controller", MessageType.Warning); 30 | return; 31 | } 32 | 33 | DrawAnimationClips(); 34 | 35 | EditorGUILayout.BeginHorizontal(); 36 | _newClipName = EditorGUILayout.TextField("New Clip Name", _newClipName); 37 | if (string.IsNullOrEmpty(_newClipName)) return; 38 | 39 | if (GUILayout.Button("+", MyGUI.ResizableToolbarButtonStyle, GUILayout.Width(20), GUILayout.Height(20))) 40 | { 41 | InsertNewClip(); 42 | } 43 | 44 | EditorGUILayout.EndHorizontal(); 45 | } 46 | 47 | private void InsertNewClip() 48 | { 49 | AnimationClip newClip = new AnimationClip(); 50 | newClip.name = _newClipName; 51 | _newClipName = string.Empty; 52 | 53 | AssetDatabase.AddObjectToAsset(newClip, _currentAnimator); 54 | _currentAnimator.AddMotion(newClip); 55 | 56 | // Reimport the asset after adding an object. 57 | // Otherwise the change only shows up when saving the project 58 | AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(newClip)); 59 | } 60 | 61 | private void DrawAnimationClips() 62 | { 63 | var clips = _currentAnimator.animationClips; 64 | if (clips == null || clips.Length == 0) return; 65 | 66 | for (var i = 0; i < clips.Length; i++) 67 | { 68 | EditorGUILayout.LabelField(i + " Clip: " + clips[i].name); 69 | } 70 | } 71 | 72 | public void OnInspectorUpdate() 73 | { 74 | Repaint(); 75 | } 76 | 77 | public void OnSelectionChange() 78 | { 79 | _currentAnimator = Selection.activeObject as AnimatorController; 80 | } 81 | } 82 | } 83 | #endif -------------------------------------------------------------------------------- /Tools/Undone/EmbeddedAnimationCreator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: af9e98dad326d9e41982c4c33829386a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/Undone/GLDraw.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 54e6acc3e64222946870d545609cbdd8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/Undone/MyLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using UnityEngine; 4 | 5 | namespace MyBox.Internal 6 | { 7 | public static class MyLogger 8 | { 9 | //TODO: How to get logs on Mac? 10 | //TODO: Find better ways for logging? 11 | 12 | private static string LogFile = "customLog.txt"; 13 | private static string TimeFormat = "MM-dd_HH-mm-ss"; 14 | 15 | public static bool Disabled; 16 | 17 | public static string Session { get; private set; } 18 | public static string Version { get; private set; } 19 | 20 | public static bool LogToConsole { get; set; } 21 | 22 | public const string DefaultFilename = "customLog.txt"; 23 | public const string DefaultTimeFormat = "MM-dd_HH-mm-ss"; 24 | 25 | private const int MaxMessageLength = 4000; 26 | 27 | static MyLogger() 28 | { 29 | AppDomain.CurrentDomain.UnhandledException += (sender, args) 30 | => LogException(args.ExceptionObject as Exception); 31 | Application.logMessageReceived += (condition, trace, type) 32 | => Log($"Console Log ({type}): {condition}{Environment.NewLine}{trace}", false, false); 33 | } 34 | 35 | public static void InitializeSession( 36 | string version = null, string filename = DefaultFilename, 37 | string timeFormat = DefaultTimeFormat, bool logToConsole = false) 38 | { 39 | Session = Guid.NewGuid().ToString(); 40 | Version = version ?? string.Empty; 41 | 42 | LogFile = filename; 43 | TimeFormat = timeFormat; 44 | 45 | LogToConsole = logToConsole; 46 | Log("Initialized. " + version); 47 | } 48 | 49 | public static void Log(string text, bool withStackTrace = false, bool logToConsole = true) 50 | { 51 | if (Application.isEditor && LogToConsole && logToConsole) 52 | Debug.Log("Logger: ".Colored(Colors.brown) + text); 53 | if (Application.isEditor) return; 54 | if (Disabled) return; 55 | 56 | string path = Path.Combine(Application.dataPath, LogFile); 57 | 58 | if (text.Length > MaxMessageLength) text = text.Substring(0, MaxMessageLength) + "..."; 59 | if (withStackTrace) text += Environment.NewLine + Environment.StackTrace; 60 | try 61 | { 62 | if (!File.Exists(path)) 63 | { 64 | using (StreamWriter sw = File.CreateText(path)) 65 | { 66 | sw.WriteLine(GetCurrentTime() + " || Log created" + Environment.NewLine); 67 | sw.WriteLine(GetCurrentTime() + ": " + text); 68 | } 69 | } 70 | else 71 | { 72 | using (StreamWriter sw = File.AppendText(path)) 73 | { 74 | sw.WriteLine(GetCurrentTime() + ": " + text); 75 | } 76 | } 77 | } 78 | catch (Exception ex) 79 | { 80 | Debug.LogException(ex); 81 | } 82 | 83 | string GetCurrentTime() => DateTime.Now.ToString(TimeFormat); 84 | } 85 | 86 | 87 | private static void LogException(Exception ex) 88 | => Log("Exception:" + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace, false, false); 89 | } 90 | } -------------------------------------------------------------------------------- /Tools/Undone/MyLogger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0b2c2e8ccd8d834f8744afc7c658044 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/Undone/SerializedPropertyViewer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f9ef337440a6d114788a9d3cd1807942 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Tools/WarningsPool.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace MyBox 5 | { 6 | /// 7 | /// This pool is used to prevent warning message spamming. 8 | /// If something was logged once it wont be logged again 9 | /// 10 | public static class WarningsPool 11 | { 12 | public static bool Log(string message, Object target = null) 13 | { 14 | if (Pool.Contains(message)) return false; 15 | 16 | if (target != null) Debug.Log(message, target); 17 | else Debug.Log(message); 18 | 19 | Pool.Add(message); 20 | return true; 21 | } 22 | 23 | public static bool LogWarning(string message, Object target = null) 24 | { 25 | if (Pool.Contains(message)) return false; 26 | 27 | if (target != null) Debug.LogWarning(message, target); 28 | else Debug.LogWarning(message); 29 | 30 | Pool.Add(message); 31 | return true; 32 | } 33 | 34 | #if UNITY_EDITOR 35 | public static bool LogWarning(Object owner, string message, Object target = null) 36 | => LogWarning($"{owner.name} caused: " + message, target); 37 | 38 | public static bool LogWarning(UnityEditor.SerializedProperty property, string message, Object target = null) 39 | => LogWarning($"Property {property.name} " + 40 | $"in Object {property.serializedObject.targetObject.name} caused: " + message, target); 41 | 42 | public static bool LogCollectionsNotSupportedWarning(UnityEditor.SerializedProperty property, string nameOfType) 43 | => LogWarning(property, $"Array fields are not supported by [{nameOfType}]. " + 44 | "Consider to use CollectionWrapper", property.serializedObject.targetObject); 45 | #endif 46 | 47 | 48 | public static bool LogError(string message, Object target = null) 49 | { 50 | if (Pool.Contains(message)) return false; 51 | 52 | if (target != null) Debug.LogError(message, target); 53 | else Debug.LogError(message); 54 | 55 | Pool.Add(message); 56 | return true; 57 | } 58 | 59 | private static readonly HashSet Pool = new HashSet(); 60 | } 61 | } -------------------------------------------------------------------------------- /Tools/WarningsPool.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a9d7afad0ff4e5a81f7d8482efba082 3 | timeCreated: 1568633644 -------------------------------------------------------------------------------- /Types.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c151963b1a328a54a9f85ae1e209a03c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Types/AnimationStateReference.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 85d01a383f214971be2d1767367b2dd0 3 | timeCreated: 1536915504 -------------------------------------------------------------------------------- /Types/AssetFolderPath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MyBox 4 | { 5 | [Serializable] 6 | public class AssetFolderPath 7 | { 8 | public string Path; 9 | } 10 | } 11 | 12 | #if UNITY_EDITOR 13 | namespace MyBox.Internal 14 | { 15 | using UnityEditor; 16 | using UnityEngine; 17 | 18 | [CustomPropertyDrawer(typeof(AssetFolderPath))] 19 | public class AssetFolderPathDrawer : PropertyDrawer 20 | { 21 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 22 | { 23 | var pathProperty = property.FindPropertyRelative("Path"); 24 | 25 | string name = label.text; 26 | string path = pathProperty.stringValue; 27 | 28 | var buttonWidth = 60; 29 | 30 | Rect textfieldBox = position; 31 | textfieldBox.width -= buttonWidth + 16; 32 | 33 | Rect buttonBox = position; 34 | buttonBox.width = buttonWidth; 35 | buttonBox.x = textfieldBox.width + 16; 36 | 37 | if (!path.Contains(Application.dataPath)) 38 | { 39 | path = Application.dataPath; 40 | } 41 | 42 | string truncatedPath = path.Substring(Application.dataPath.Length); 43 | string filepath = Application.dataPath + EditorGUI.TextField(textfieldBox, name, truncatedPath); 44 | if (GUI.Button(buttonBox, "Browse")) 45 | { 46 | var newPath = EditorUtility.SaveFolderPanel(name, path, "Select Folder"); 47 | if (newPath.Length > 0) filepath = newPath; 48 | 49 | if (!filepath.Contains(Application.dataPath)) 50 | { 51 | Debug.LogError("Please choose a folder that is in this Assets Folder"); 52 | 53 | pathProperty.stringValue = path; 54 | return; 55 | } 56 | } 57 | 58 | pathProperty.stringValue = filepath; 59 | } 60 | } 61 | } 62 | #endif -------------------------------------------------------------------------------- /Types/AssetFolderPath.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c5b0377a856a42d880420a1046711a8a 3 | timeCreated: 1568525388 -------------------------------------------------------------------------------- /Types/AssetPath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MyBox 4 | { 5 | [Serializable] 6 | public class AssetPath 7 | { 8 | public string Path; 9 | public string Extension; 10 | 11 | public static AssetPath WithExtension(string extension) 12 | { 13 | var assetPath = new AssetPath(); 14 | assetPath.Extension = extension; 15 | return assetPath; 16 | } 17 | } 18 | } 19 | 20 | #if UNITY_EDITOR 21 | namespace MyBox.Internal 22 | { 23 | using UnityEditor; 24 | using UnityEngine; 25 | 26 | [CustomPropertyDrawer(typeof(AssetPath))] 27 | public class AssetPathDrawer : PropertyDrawer 28 | { 29 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 30 | { 31 | var pathProperty = property.FindPropertyRelative("Path"); 32 | var extensionProperty = property.FindPropertyRelative("Extension"); 33 | 34 | string name = label.text; 35 | string path = pathProperty.stringValue; 36 | 37 | var buttonWidth = 60; 38 | 39 | Rect textfieldBox = position; 40 | textfieldBox.width -= buttonWidth + 16; 41 | 42 | Rect buttonBox = position; 43 | buttonBox.width = buttonWidth; 44 | buttonBox.x = textfieldBox.width + 16; 45 | 46 | if (!path.Contains(Application.dataPath)) 47 | { 48 | path = Application.dataPath; 49 | } 50 | 51 | string truncatedPath = path.Substring(Application.dataPath.Length); 52 | string filepath = Application.dataPath + EditorGUI.TextField(textfieldBox, name, truncatedPath); 53 | if (GUI.Button(buttonBox, "Browse")) 54 | { 55 | var newPath = EditorUtility.OpenFilePanel(name, path, extensionProperty.stringValue); 56 | if (newPath.Length > 0) filepath = newPath; 57 | 58 | if (!filepath.Contains(Application.dataPath)) 59 | { 60 | Debug.LogError("Please choose a asset that is in this Assets Folder"); 61 | 62 | pathProperty.stringValue = path; 63 | return; 64 | } 65 | } 66 | 67 | pathProperty.stringValue = filepath; 68 | } 69 | } 70 | } 71 | #endif -------------------------------------------------------------------------------- /Types/AssetPath.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d6bdce985c9d49fc95b005025663e606 3 | timeCreated: 1568526276 -------------------------------------------------------------------------------- /Types/Billboard.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | [ExecuteAlways] 6 | public class Billboard : MonoBehaviour 7 | { 8 | [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] 9 | private static void Initialize() 10 | { 11 | _camera = null; 12 | } 13 | 14 | public Transform FacedObject; 15 | 16 | private Transform ActiveFacedObject 17 | { 18 | get 19 | { 20 | if (FacedObject != null) return FacedObject; 21 | if (_camera != null) return _camera.transform; 22 | _camera = Camera.main; 23 | 24 | return _camera == null ? null : _camera.transform; 25 | } 26 | } 27 | private static Camera _camera; 28 | 29 | private void Update() 30 | { 31 | if (ActiveFacedObject == null) return; 32 | transform.LookAt(ActiveFacedObject); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Types/Billboard.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3ec44ed11e3fdf541937f2a2b8c62d87 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/CollectionWrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using MyBox.Internal; 4 | 5 | namespace MyBox 6 | { 7 | /// 8 | /// CollectionWrapper used to apply custom drawers to Array fields 9 | /// 10 | [Serializable] 11 | public class CollectionWrapper : CollectionWrapperBase 12 | { 13 | public T[] Value; 14 | } 15 | /// 16 | /// CollectionWrapper used to apply custom drawers to List fields 17 | /// 18 | [Serializable] 19 | public class CollectionWrapperList : CollectionWrapperBase 20 | { 21 | public List Value = new List(); 22 | } 23 | } 24 | 25 | namespace MyBox.Internal 26 | { 27 | [Serializable] 28 | public class CollectionWrapperBase {} 29 | } 30 | 31 | #if UNITY_EDITOR 32 | namespace MyBox.Internal 33 | { 34 | using UnityEditor; 35 | using UnityEngine; 36 | 37 | [CustomPropertyDrawer(typeof(CollectionWrapperBase), true)] 38 | public class CollectionWrapperDrawer : PropertyDrawer 39 | { 40 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 41 | { 42 | var collection = property.FindPropertyRelative("Value"); 43 | return EditorGUI.GetPropertyHeight(collection, true); 44 | } 45 | 46 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 47 | { 48 | var collection = property.FindPropertyRelative("Value"); 49 | EditorGUI.PropertyField(position, collection, label, true); 50 | } 51 | } 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /Types/CollectionWrapper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e4a3ca56e8c64495af77fc8d367d7913 3 | timeCreated: 1589774388 -------------------------------------------------------------------------------- /Types/ColliderGizmo.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e1cd926bb9d510543847bc79ae7379f9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/ColliderToMesh.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 134a4a5740fe6de41bb8c6c32aeb784a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/CommentaryComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee85920dbe024568b894f71d5bb75c1e 3 | timeCreated: 1568812847 -------------------------------------------------------------------------------- /Types/CoroutineGroup.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | public class CoroutineGroup 8 | { 9 | public int ActiveCoroutinesAmount => _activeCoroutines.Count; 10 | public bool AnyProcessing => _activeCoroutines.Count > 0; 11 | 12 | public CoroutineGroup(MonoBehaviour owner) 13 | { 14 | _owner = owner; 15 | } 16 | 17 | public Coroutine StartCoroutine(IEnumerator coroutine) 18 | { 19 | return _owner.StartCoroutine(DoStart(coroutine)); 20 | } 21 | 22 | public void StopAll() 23 | { 24 | for (var i = 0; i < _activeCoroutines.Count; i++) 25 | _owner.StopCoroutine(_activeCoroutines[i]); 26 | } 27 | 28 | private readonly MonoBehaviour _owner; 29 | private readonly List _activeCoroutines = new List(); 30 | 31 | private IEnumerator DoStart(IEnumerator coroutine) 32 | { 33 | var started = _owner.StartCoroutine(coroutine); 34 | 35 | _activeCoroutines.Add(started); 36 | yield return started; 37 | _activeCoroutines.Remove(started); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Types/CoroutineGroup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b47a3601930046e7b6ae87cfbb39749a 3 | timeCreated: 1623144790 -------------------------------------------------------------------------------- /Types/EditorTypes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7e10560d47ca4924cb5d98676e0ea567 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Types/EditorTypes/ConditionallyColoredGUIBlock.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using UnityEngine; 4 | 5 | namespace MyBox.EditorTools 6 | { 7 | public class ConditionallyColoredGUIBlock : IDisposable 8 | { 9 | private readonly Color _originalColor; 10 | 11 | public ConditionallyColoredGUIBlock(bool condition, Color color) 12 | { 13 | _originalColor = GUI.color; 14 | 15 | if (condition) GUI.color = color; 16 | } 17 | 18 | public void Dispose() 19 | { 20 | GUI.color = _originalColor; 21 | } 22 | } 23 | } 24 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/ConditionallyColoredGUIBlock.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 39b867fda15ebe443a93712a809c93c1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/EditorTypes/ConditionallyEnabledGUIBlock.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using UnityEngine; 4 | 5 | namespace MyBox.EditorTools 6 | { 7 | public class ConditionallyEnabledGUIBlock : IDisposable 8 | { 9 | private readonly bool _originalState; 10 | 11 | public ConditionallyEnabledGUIBlock(bool condition) 12 | { 13 | _originalState = GUI.enabled; 14 | GUI.enabled = condition; 15 | } 16 | 17 | public void Dispose() 18 | { 19 | GUI.enabled = _originalState; 20 | } 21 | } 22 | } 23 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/ConditionallyEnabledGUIBlock.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d80ab2dc89c871446a0715356e9c15ec 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/EditorTypes/DraggableHandler.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 507cee406837a404f808ba3333c51db3 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsBool.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using UnityEditor; 4 | 5 | namespace MyBox.EditorTools 6 | { 7 | [Serializable] 8 | public class EditorPrefsBool : EditorPrefsType 9 | { 10 | public bool Value 11 | { 12 | get => EditorPrefs.GetBool(Key, DefaultValue); 13 | set => EditorPrefs.SetBool(Key, value); 14 | } 15 | 16 | public bool DefaultValue; 17 | 18 | public static EditorPrefsBool WithKey(string key, bool defaultValue = false) => new EditorPrefsBool(key, defaultValue); 19 | 20 | public void Toggle() => Value = !Value; 21 | 22 | public EditorPrefsBool(string key, bool defaultValue = false) 23 | { 24 | Key = key; 25 | DefaultValue = defaultValue; 26 | } 27 | } 28 | } 29 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsBool.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5af0fb19d90647af820764719994083c 3 | timeCreated: 1601034260 -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsFloat.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using UnityEditor; 4 | 5 | namespace MyBox.EditorTools 6 | { 7 | [Serializable] 8 | public class EditorPrefsFloat : EditorPrefsType 9 | { 10 | public float Value 11 | { 12 | get => EditorPrefs.GetFloat(Key, DefaultValue); 13 | set => EditorPrefs.SetFloat(Key, value); 14 | } 15 | 16 | public float DefaultValue; 17 | 18 | public static EditorPrefsFloat WithKey(string key, float defaultValue = 0) => new EditorPrefsFloat(key, defaultValue); 19 | 20 | public EditorPrefsFloat(string key, float defaultValue = 0) 21 | { 22 | Key = key; 23 | DefaultValue = defaultValue; 24 | } 25 | } 26 | } 27 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsFloat.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 09c02eb3aa8f4a95a8746884d79e9890 3 | timeCreated: 1630590480 -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsInt.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | namespace MyBox.EditorTools 3 | { 4 | using System; 5 | using UnityEditor; 6 | 7 | [Serializable] 8 | public class EditorPrefsInt : EditorPrefsType 9 | { 10 | public int Value 11 | { 12 | get => (int)EditorPrefs.GetFloat(Key, DefaultValue); 13 | set => EditorPrefs.SetFloat(Key, value); 14 | } 15 | 16 | public int DefaultValue; 17 | 18 | public static EditorPrefsInt WithKey(string key, int defaultValue = 0) => new EditorPrefsInt(key, defaultValue); 19 | 20 | public EditorPrefsInt(string key, int defaultValue = 0) 21 | { 22 | Key = key; 23 | DefaultValue = defaultValue; 24 | } 25 | } 26 | } 27 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsInt.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: befa908d4bb3444f8be043d501272621 3 | timeCreated: 1641816922 -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsString.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using UnityEditor; 4 | 5 | namespace MyBox.EditorTools 6 | { 7 | [Serializable] 8 | public class EditorPrefsString : EditorPrefsType 9 | { 10 | public string Value 11 | { 12 | get => EditorPrefs.GetString(Key, DefaultValue); 13 | set => EditorPrefs.SetString(Key, value); 14 | } 15 | 16 | public string DefaultValue; 17 | 18 | public static EditorPrefsString WithKey(string key, string defaultValue = "") => new EditorPrefsString(key, defaultValue); 19 | 20 | public EditorPrefsString(string key, string defaultValue = "") 21 | { 22 | Key = key; 23 | DefaultValue = defaultValue; 24 | } 25 | } 26 | } 27 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsString.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0ff7722b2eac41839248b7c9fbb94553 3 | timeCreated: 1596099663 -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsType.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using UnityEditor; 4 | 5 | namespace MyBox.EditorTools 6 | { 7 | [Serializable] 8 | public class EditorPrefsType 9 | { 10 | public string Key { get; protected set; } 11 | 12 | /// 13 | /// Is this pref contains any value 14 | /// 15 | public bool IsSet => EditorPrefs.HasKey(Key); 16 | 17 | public void Delete() => EditorPrefs.DeleteKey(Key); 18 | } 19 | } 20 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsType.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1aa41a242bf946419e7c94a5c7986d1f 3 | timeCreated: 1630589529 -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsVector3.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | namespace MyBox.EditorTools 7 | { 8 | [Serializable] 9 | public class EditorPrefsVector3 : EditorPrefsType 10 | { 11 | public Vector3 Value 12 | { 13 | get => new Vector3( 14 | EditorPrefs.GetFloat(Key+"x", DefaultValue.x), 15 | EditorPrefs.GetFloat(Key+"y", DefaultValue.y), 16 | EditorPrefs.GetFloat(Key+"z", DefaultValue.z)); 17 | set 18 | { 19 | EditorPrefs.SetFloat(Key+"x", value.x); 20 | EditorPrefs.SetFloat(Key+"y", value.y); 21 | EditorPrefs.SetFloat(Key+"z", value.z); 22 | } 23 | } 24 | 25 | public Vector3 DefaultValue; 26 | 27 | public static EditorPrefsVector3 WithKey(string key, Vector3 defaultValue = new Vector3()) => new EditorPrefsVector3(key, defaultValue); 28 | 29 | public EditorPrefsVector3(string key, Vector3 defaultValue = new Vector3()) 30 | { 31 | Key = key; 32 | DefaultValue = defaultValue; 33 | } 34 | } 35 | } 36 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/EditorPrefsVector3.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b34cc5b7bd1483893108b73a64ca0e8 3 | timeCreated: 1596101415 -------------------------------------------------------------------------------- /Types/EditorTypes/EditorWithSubEditors.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using UnityEditor; 4 | 5 | namespace MyBox.EditorTools 6 | { 7 | // Interesting approach for nested editors from Adventure Game Unity tutorial 8 | // www.unity3d.com/ru/learn/tutorials/projects/adventure-game-tutorial/conditions?playlist=44381 9 | public abstract class EditorWithSubEditors : Editor where TEditor : Editor where TTarget : Object 10 | { 11 | protected TEditor[] SubEditors; 12 | 13 | 14 | protected void CheckAndCreateSubEditors(TTarget[] subEditorTargets) 15 | { 16 | if (SubEditors != null && SubEditors.Length == subEditorTargets.Length) 17 | return; 18 | 19 | CleanupEditors(); 20 | 21 | SubEditors = new TEditor[subEditorTargets.Length]; 22 | 23 | for (int i = 0; i < SubEditors.Length; i++) 24 | { 25 | SubEditors[i] = CreateEditor(subEditorTargets[i]) as TEditor; 26 | SubEditorSetup(SubEditors[i]); 27 | } 28 | } 29 | 30 | 31 | protected void CleanupEditors() 32 | { 33 | if (SubEditors == null) 34 | return; 35 | 36 | for (int i = 0; i < SubEditors.Length; i++) 37 | { 38 | DestroyImmediate(SubEditors[i]); 39 | } 40 | 41 | SubEditors = null; 42 | } 43 | 44 | 45 | protected abstract void SubEditorSetup(TEditor editor); 46 | } 47 | } 48 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/EditorWithSubEditors.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9ef1d5208f86bb438938f55da5d07b8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/EditorTypes/IndentBlock.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | using System; 4 | 5 | namespace MyBox.EditorTools 6 | { 7 | public class IndentBlock : IDisposable 8 | { 9 | public IndentBlock() 10 | { 11 | EditorGUI.indentLevel++; 12 | } 13 | 14 | public void Dispose() 15 | { 16 | EditorGUI.indentLevel--; 17 | } 18 | } 19 | } 20 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/IndentBlock.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 31a07d7247a9ed4429fdc57aa366f9fd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/EditorTypes/ReorderableCollection.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a8079b7376c142bf9e6258a4daf14cfa 3 | timeCreated: 1550230236 -------------------------------------------------------------------------------- /Types/EditorTypes/SceneClickHandler.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7a348743aa5178f4db1a0b4fcb9bad39 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/EditorTypes/ScrollViewBlock.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEngine; 3 | using UnityEditor; 4 | using System; 5 | 6 | namespace MyBox.EditorTools 7 | { 8 | public class ScrollViewBlock : IDisposable 9 | { 10 | public ScrollViewBlock(ref Vector2 scrollPosition, params GUILayoutOption[] options) 11 | { 12 | scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, options); 13 | } 14 | 15 | public void Dispose() 16 | { 17 | EditorGUILayout.EndScrollView(); 18 | } 19 | } 20 | } 21 | #endif -------------------------------------------------------------------------------- /Types/EditorTypes/ScrollViewBlock.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 945efb5cb70bac240b6d8fe987f009c9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/FPSCounter.cs: -------------------------------------------------------------------------------- 1 | using MyBox; 2 | using UnityEngine; 3 | 4 | public class FPSCounter : MonoBehaviour 5 | { 6 | public bool EditorOnly; 7 | 8 | [SerializeField] private float _updateInterval = 1f; 9 | [SerializeField] private int _targetFrameRate = 30; 10 | 11 | #pragma warning disable 0649 12 | [SerializeField] private Anchor _anchor; 13 | [SerializeField] private int _xOffset; 14 | [SerializeField] private int _yOffset; 15 | #pragma warning restore 0649 16 | 17 | /// 18 | /// Skip some time at start to skip performance drop on game start 19 | /// and produce more accurate Avg FPS 20 | /// 21 | private float _idleTime = 2; 22 | 23 | private float _elapsed; 24 | private int _frames; 25 | private int _quantity; 26 | private float _fps; 27 | private float _averageFps; 28 | 29 | private Color _goodColor; 30 | private Color _okColor; 31 | private Color _badColor; 32 | 33 | private float _okFps; 34 | private float _badFps; 35 | 36 | private Rect _rect1; 37 | private Rect _rect2; 38 | 39 | private void Awake() 40 | { 41 | if (EditorOnly && !Application.isEditor) return; 42 | 43 | _goodColor = new Color(.4f, .6f, .4f); 44 | _okColor = new Color(.8f, .8f, .2f, .6f); 45 | _badColor = new Color(.8f, .6f, .6f); 46 | 47 | var percent = _targetFrameRate / 100; 48 | var percent10 = percent * 10; 49 | var percent40 = percent * 40; 50 | _okFps = _targetFrameRate - percent10; 51 | _badFps = _targetFrameRate - percent40; 52 | 53 | var xPos = 0; 54 | var yPos = 0; 55 | var linesHeight = 40; 56 | var linesWidth = 90; 57 | if (_anchor == Anchor.LeftBottom || _anchor == Anchor.RightBottom) yPos = Screen.height - linesHeight; 58 | if (_anchor == Anchor.RightTop || _anchor == Anchor.RightBottom) xPos = Screen.width - linesWidth; 59 | xPos += _xOffset; 60 | yPos += _yOffset; 61 | var yPos2 = yPos + 18; 62 | _rect1 = new Rect(xPos, yPos, linesWidth, linesHeight); 63 | _rect2 = new Rect(xPos, yPos2, linesWidth, linesHeight); 64 | 65 | _elapsed = _updateInterval; 66 | } 67 | 68 | private void Update() 69 | { 70 | if (EditorOnly && !Application.isEditor) return; 71 | 72 | if (_idleTime > 0) 73 | { 74 | _idleTime -= Time.deltaTime; 75 | return; 76 | } 77 | 78 | _elapsed += Time.deltaTime; 79 | ++_frames; 80 | 81 | if (_elapsed >= _updateInterval) 82 | { 83 | _fps = _frames / _elapsed; 84 | _elapsed = 0; 85 | _frames = 0; 86 | } 87 | 88 | _quantity++; 89 | _averageFps += (_fps - _averageFps) / _quantity; 90 | } 91 | 92 | private void OnGUI() 93 | { 94 | if (EditorOnly && !Application.isEditor) return; 95 | 96 | var defaultColor = GUI.color; 97 | var color = _goodColor; 98 | if (_fps <= _okFps || _averageFps <= _okFps) color = _okColor; 99 | if (_fps <= _badFps || _averageFps <= _badFps) color = _badColor; 100 | GUI.color = color; 101 | GUI.Label(_rect1, "FPS: " + (int)_fps); 102 | //GUI.Label(_rect2, "Avg FPS: " + (int)_averageFps); 103 | GUI.color = defaultColor; 104 | } 105 | 106 | private enum Anchor 107 | { 108 | LeftTop, LeftBottom, RightTop, RightBottom 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Types/FPSCounter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3b7bca08cff38b447b15fea934b94383 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/GUID.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 137e83b0e0d08914c83561d786e1624c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Types/GUID/Credits.txt: -------------------------------------------------------------------------------- 1 | Official GUID based reference solution from Unity. 2 | Included in MyBox because I personally use it almost in every project :) 3 | And also with a few additions, like public Guid and GuidString properties. 4 | 5 | 6 | https://github.com/Unity-Technologies/guid-based-reference 7 | Version Aug 29, 2019 -------------------------------------------------------------------------------- /Types/GUID/Credits.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c6907de46feb8284a821a8b23fdc52e4 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Types/GUID/GUIDEditor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ab3f0d3c87f4e4542b3fca67cd6ae5e8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Types/GUID/GUIDEditor/GuidComponentDrawer.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using UnityEditor; 3 | 4 | namespace MyBox.Internal 5 | { 6 | [CustomEditor(typeof(GuidComponent))] 7 | public class GuidComponentDrawer : Editor 8 | { 9 | private GuidComponent _guid; 10 | 11 | public override void OnInspectorGUI() 12 | { 13 | if (_guid == null) _guid = (GuidComponent) target; 14 | 15 | using (new EditorGUI.DisabledScope(true)) EditorGUILayout.TextField("Guid:", _guid.GetGuid().ToString()); 16 | } 17 | } 18 | } 19 | #endif -------------------------------------------------------------------------------- /Types/GUID/GUIDEditor/GuidComponentDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d391a6c68619db747b22b71468282c7f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/GUID/GUIDEditor/GuidReferenceDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2bca965b1349294cab5244279477c6d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/GUID/GuidComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98bbc2c1e63e98543830eec78d976795 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/GUID/GuidManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a025fc98970524f4fafbe145be2d52d9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/GUID/GuidReference.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | 4 | #if UNITY_EDITOR 5 | using UnityEditor; 6 | #endif 7 | 8 | namespace MyBox 9 | { 10 | /// 11 | /// This call is the type used by any other code to hold a reference to an object by GUID 12 | /// If the target object is loaded, it will be returned, otherwise, NULL will be returned 13 | /// This always works in Game Objects, so calling code will need to use GetComponent<> 14 | /// or other methods to track down the specific objects need by any given system 15 | /// Ideally this would be a struct, but we need the ISerializationCallbackReciever 16 | /// 17 | [Serializable] 18 | public class GuidReference : ISerializationCallbackReceiver 19 | { 20 | // cache the referenced Game Object if we find one for performance 21 | private GameObject cachedReference; 22 | private bool isCacheSet; 23 | 24 | // store our GUID in a form that Unity can save 25 | [SerializeField] private byte[] serializedGuid; 26 | private Guid guid; 27 | 28 | #if UNITY_EDITOR 29 | // decorate with some extra info in Editor so we can inform a user of what that GUID means 30 | [SerializeField] private string cachedName; 31 | [SerializeField] private SceneAsset cachedScene; 32 | #endif 33 | 34 | // Set up events to let users register to cleanup their own cached references on destroy or to cache off values 35 | public event Action OnGuidAdded = delegate(GameObject go) { }; 36 | public event Action OnGuidRemoved = delegate() { }; 37 | 38 | // create concrete delegates to avoid boxing. 39 | // When called 10,000 times, boxing would allocate ~1MB of GC Memory 40 | private Action addDelegate; 41 | private Action removeDelegate; 42 | 43 | // optimized accessor, and ideally the only code you ever call on this class 44 | public GameObject gameObject 45 | { 46 | get 47 | { 48 | if (isCacheSet) 49 | { 50 | return cachedReference; 51 | } 52 | 53 | cachedReference = GuidManager.ResolveGuid(guid, addDelegate, removeDelegate); 54 | isCacheSet = true; 55 | return cachedReference; 56 | } 57 | 58 | private set { } 59 | } 60 | 61 | public GuidReference() 62 | { 63 | } 64 | 65 | public GuidReference(GuidComponent target) 66 | { 67 | guid = target.GetGuid(); 68 | } 69 | 70 | private void GuidAdded(GameObject go) 71 | { 72 | cachedReference = go; 73 | OnGuidAdded(go); 74 | } 75 | 76 | private void GuidRemoved() 77 | { 78 | cachedReference = null; 79 | isCacheSet = false; 80 | OnGuidRemoved(); 81 | } 82 | 83 | //convert system guid to a format unity likes to work with 84 | public void OnBeforeSerialize() 85 | { 86 | serializedGuid = guid.ToByteArray(); 87 | } 88 | 89 | // convert from byte array to system guid and reset state 90 | public void OnAfterDeserialize() 91 | { 92 | cachedReference = null; 93 | isCacheSet = false; 94 | if (serializedGuid == null || serializedGuid.Length != 16) 95 | { 96 | serializedGuid = new byte[16]; 97 | } 98 | 99 | guid = new System.Guid(serializedGuid); 100 | addDelegate = GuidAdded; 101 | removeDelegate = GuidRemoved; 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /Types/GUID/GuidReference.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 061c5c53f1e3d044fbe53d54e6f5ceb9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/MinMax.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 09481c105437911469e8eaac9c304db4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/MyCursor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2e55354cc1054ccc83f73af74ccfb15f 3 | timeCreated: 1579693030 -------------------------------------------------------------------------------- /Types/MyDictionary.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83db1ec063a5ac1478f780dacf6b8d8e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/Optional.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b0fd3dadb3ef42299beef4af9cb1d5b1 3 | timeCreated: 1551621960 -------------------------------------------------------------------------------- /Types/OptionalMinMax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MyBox 4 | { 5 | /// 6 | /// Type to set Min/Max values but with optional Min and Max 7 | /// 8 | [Serializable] 9 | public struct OptionalMinMax 10 | { 11 | public bool MinIsSet; 12 | public bool MaxIsSet; 13 | 14 | public float Min; 15 | public float Max; 16 | 17 | public float GetFixed(float value) 18 | { 19 | if (MinIsSet && value < Min) value = Min; 20 | if (MaxIsSet && value > Max) value = Max; 21 | 22 | return value; 23 | } 24 | 25 | public OptionalMinMax(bool minIsSet, bool maxIsSet, float min, float max) 26 | { 27 | MinIsSet = minIsSet; 28 | MaxIsSet = maxIsSet; 29 | Min = min; 30 | Max = max; 31 | } 32 | } 33 | } 34 | 35 | #if UNITY_EDITOR 36 | namespace MyBox.Internal 37 | { 38 | using UnityEditor; 39 | using UnityEngine; 40 | 41 | [CustomPropertyDrawer(typeof (OptionalMinMax))] 42 | public class MinMaxFloatPropertyDrawer : PropertyDrawer 43 | { 44 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 45 | { 46 | EditorGUI.BeginProperty(position, label, property); 47 | position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); 48 | EditorGUI.indentLevel = 0; // PropertyDrawer Indent fix for nested inspectors 49 | 50 | var minProp = property.FindPropertyRelative("Min"); 51 | var maxProp = property.FindPropertyRelative("Max"); 52 | var minCheckProp = property.FindPropertyRelative("MinIsSet"); 53 | var maxCheckProp = property.FindPropertyRelative("MaxIsSet"); 54 | 55 | var minMaxLabel = "Min : Max"; 56 | var labelWidth = 58; 57 | var checkWidth = 14; 58 | var spaceWidth = 4; 59 | var valWidth = (position.width / 2) - (labelWidth / 2f) - (spaceWidth * 4) - checkWidth + 2; 60 | 61 | position.width = valWidth; 62 | if (minCheckProp.boolValue) EditorGUI.PropertyField(position, minProp, GUIContent.none); 63 | 64 | position.x += valWidth + spaceWidth; 65 | position.width = checkWidth; 66 | minCheckProp.boolValue = EditorGUI.Toggle(position, GUIContent.none, minCheckProp.boolValue); 67 | 68 | position.x += checkWidth + spaceWidth; 69 | position.width = labelWidth; 70 | EditorGUI.LabelField(position, minMaxLabel); 71 | 72 | position.x += labelWidth + spaceWidth; 73 | position.width = checkWidth; 74 | maxCheckProp.boolValue = EditorGUI.Toggle(position, GUIContent.none, maxCheckProp.boolValue); 75 | 76 | position.x += checkWidth + spaceWidth; 77 | position.width = valWidth; 78 | if (maxCheckProp.boolValue) EditorGUI.PropertyField(position, maxProp, GUIContent.none); 79 | 80 | if (GUI.changed) 81 | { 82 | if (maxCheckProp.boolValue && maxCheckProp.boolValue) 83 | { 84 | if (maxProp.floatValue < minProp.floatValue) maxProp.floatValue = minProp.floatValue; 85 | } 86 | property.serializedObject.ApplyModifiedProperties(); 87 | } 88 | 89 | EditorGUI.EndProperty(); 90 | } 91 | } 92 | } 93 | #endif -------------------------------------------------------------------------------- /Types/OptionalMinMax.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e01709a13cd37154484e0ef58ac23652 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/PlayerPrefsBool.cs: -------------------------------------------------------------------------------- 1 | using MyBox.Internal; 2 | using UnityEngine; 3 | 4 | namespace MyBox 5 | { 6 | public class PlayerPrefsBool : PlayerPrefsType 7 | { 8 | public bool Value 9 | { 10 | get => PlayerPrefs.GetInt(Key, DefaultValue ? 1 : 0) == 1; 11 | set => PlayerPrefs.SetInt(Key, value ? 1 : 0); 12 | } 13 | public bool DefaultValue; 14 | 15 | public static PlayerPrefsBool WithKey(string key, bool defaultValue = false) => new PlayerPrefsBool(key); 16 | 17 | public PlayerPrefsBool(string key, bool defaultValue = false) 18 | { 19 | Key = key; 20 | DefaultValue = defaultValue; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Types/PlayerPrefsBool.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0da3e0d36d734cd58cc4909673d6832c 3 | timeCreated: 1630590006 -------------------------------------------------------------------------------- /Types/PlayerPrefsFloat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MyBox.Internal; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | [Serializable] 8 | public class PlayerPrefsFloat : PlayerPrefsType 9 | { 10 | public float Value 11 | { 12 | get => PlayerPrefs.GetFloat(Key, DefaultValue); 13 | set => PlayerPrefs.SetFloat(Key, value); 14 | } 15 | public float DefaultValue; 16 | 17 | 18 | public static PlayerPrefsFloat WithKey(string key, float defaultValue = 0) => new PlayerPrefsFloat(key, defaultValue); 19 | 20 | public PlayerPrefsFloat(string key, float defaultValue = 0) 21 | { 22 | Key = key; 23 | DefaultValue = defaultValue; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Types/PlayerPrefsFloat.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 66c1b046dafd4e21882d52bea024d15e 3 | timeCreated: 1630586841 -------------------------------------------------------------------------------- /Types/PlayerPrefsInt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MyBox.Internal; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | [Serializable] 8 | public class PlayerPrefsInt : PlayerPrefsType 9 | { 10 | public int Value 11 | { 12 | get => PlayerPrefs.GetInt(Key, DefaultValue); 13 | set => PlayerPrefs.SetInt(Key, value); 14 | } 15 | 16 | public int DefaultValue; 17 | 18 | public static PlayerPrefsInt WithKey(string key, int defaultValue = 0) => new PlayerPrefsInt(key, defaultValue); 19 | 20 | public PlayerPrefsInt(string key, int defaultValue = 0) 21 | { 22 | Key = key; 23 | DefaultValue = defaultValue; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Types/PlayerPrefsInt.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: abf06d2ac7a2454390eada61bd0c528c 3 | timeCreated: 1630587303 -------------------------------------------------------------------------------- /Types/PlayerPrefsString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MyBox.Internal; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | [Serializable] 8 | public class PlayerPrefsString : PlayerPrefsType 9 | { 10 | public string Value 11 | { 12 | get => PlayerPrefs.GetString(Key, DefaultString); 13 | set => PlayerPrefs.SetString(Key, value); 14 | } 15 | 16 | public string DefaultString; 17 | 18 | public static PlayerPrefsString WithKey(string key, string defaultString = "") => new PlayerPrefsString(key, defaultString); 19 | 20 | public PlayerPrefsString(string key, string defaultString = "") 21 | { 22 | Key = key; 23 | DefaultString = defaultString; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Types/PlayerPrefsString.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fcc3a91c05ca47c28ba86452dd44e15a 3 | timeCreated: 1630588512 -------------------------------------------------------------------------------- /Types/PlayerPrefsType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace MyBox.Internal 5 | { 6 | [Serializable] 7 | public abstract class PlayerPrefsType 8 | { 9 | public string Key { get; protected set; } 10 | 11 | public bool IsSet => PlayerPrefs.HasKey(Key); 12 | 13 | public void Delete() => PlayerPrefs.DeleteKey(Key); 14 | } 15 | } -------------------------------------------------------------------------------- /Types/PlayerPrefsType.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cac81fbea2ff4df8aa5bfe75e93b8f8d 3 | timeCreated: 1630588525 -------------------------------------------------------------------------------- /Types/PlayerPrefsVector2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MyBox.Internal; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | [Serializable] 8 | public class PlayerPrefsVector2 : PlayerPrefsType 9 | { 10 | public Vector2 Value 11 | { 12 | get => new Vector2( 13 | PlayerPrefs.GetFloat(Key + "x", DefaultValue.x), 14 | PlayerPrefs.GetFloat(Key + "y", DefaultValue.y)); 15 | set 16 | { 17 | PlayerPrefs.SetFloat(Key + "x", value.x); 18 | PlayerPrefs.SetFloat(Key + "y", value.y); 19 | } 20 | } 21 | 22 | public Vector2 DefaultValue; 23 | 24 | public static PlayerPrefsVector2 WithKey(string key, Vector2 defaultValue = new Vector2()) => 25 | new PlayerPrefsVector2(key, defaultValue); 26 | 27 | public PlayerPrefsVector2(string key, Vector2 defaultValue = new Vector2()) 28 | { 29 | Key = key; 30 | DefaultValue = defaultValue; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Types/PlayerPrefsVector2.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f464605a8ba94023b175ccebe73b9143 3 | timeCreated: 1692081739 -------------------------------------------------------------------------------- /Types/PlayerPrefsVector2Int.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MyBox.Internal; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | [Serializable] 8 | public class PlayerPrefsVector2Int : PlayerPrefsType 9 | { 10 | public Vector2Int Value 11 | { 12 | get => new Vector2Int( 13 | PlayerPrefs.GetInt(Key + "x", DefaultValue.x), 14 | PlayerPrefs.GetInt(Key + "y", DefaultValue.y)); 15 | set 16 | { 17 | PlayerPrefs.SetInt(Key + "x", value.x); 18 | PlayerPrefs.SetInt(Key + "y", value.y); 19 | } 20 | } 21 | 22 | public Vector2Int DefaultValue; 23 | 24 | public static PlayerPrefsVector2Int WithKey(string key, Vector2Int defaultValue = new Vector2Int()) => 25 | new PlayerPrefsVector2Int(key, defaultValue); 26 | 27 | public PlayerPrefsVector2Int(string key, Vector2Int defaultValue = new Vector2Int()) 28 | { 29 | Key = key; 30 | DefaultValue = defaultValue; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Types/PlayerPrefsVector2Int.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 90bae5ac7f334a2b95ff64bb034a03bb 3 | timeCreated: 1671621892 -------------------------------------------------------------------------------- /Types/PlayerPrefsVector3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MyBox.Internal; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | [Serializable] 8 | public class PlayerPrefsVector3 : PlayerPrefsType 9 | { 10 | public Vector3 Value 11 | { 12 | get => new Vector3( 13 | PlayerPrefs.GetFloat(Key+"x", DefaultValue.x), 14 | PlayerPrefs.GetFloat(Key+"y", DefaultValue.y), 15 | PlayerPrefs.GetFloat(Key+"z", DefaultValue.z)); 16 | set 17 | { 18 | PlayerPrefs.SetFloat(Key+"x", value.x); 19 | PlayerPrefs.SetFloat(Key+"y", value.y); 20 | PlayerPrefs.SetFloat(Key+"z", value.z); 21 | } 22 | } 23 | public Vector3 DefaultValue; 24 | 25 | public static PlayerPrefsVector3 WithKey(string key, Vector3 defaultValue = new Vector3()) => new PlayerPrefsVector3(key, defaultValue); 26 | 27 | public PlayerPrefsVector3(string key, Vector3 defaultValue = new Vector3()) 28 | { 29 | Key = key; 30 | DefaultValue = defaultValue; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Types/PlayerPrefsVector3.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 579c1a5a9518425b9a17277443dff889 3 | timeCreated: 1630589323 -------------------------------------------------------------------------------- /Types/PlayerPrefsVector3Int.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MyBox.Internal; 3 | using UnityEngine; 4 | 5 | namespace MyBox 6 | { 7 | [Serializable] 8 | public class PlayerPrefsVector3Int : PlayerPrefsType 9 | { 10 | public Vector3Int Value 11 | { 12 | get => new Vector3Int( 13 | PlayerPrefs.GetInt(Key + "x", DefaultValue.x), 14 | PlayerPrefs.GetInt(Key + "y", DefaultValue.y), 15 | PlayerPrefs.GetInt(Key + "z", DefaultValue.z)); 16 | set 17 | { 18 | PlayerPrefs.SetInt(Key + "x", value.x); 19 | PlayerPrefs.SetInt(Key + "y", value.y); 20 | PlayerPrefs.SetInt(Key + "z", value.z); 21 | } 22 | } 23 | 24 | public Vector3Int DefaultValue; 25 | 26 | public static PlayerPrefsVector3Int WithKey(string key, Vector3Int defaultValue = new Vector3Int()) => 27 | new PlayerPrefsVector3Int(key, defaultValue); 28 | 29 | public PlayerPrefsVector3Int(string key, Vector3Int defaultValue = new Vector3Int()) 30 | { 31 | Key = key; 32 | DefaultValue = defaultValue; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Types/PlayerPrefsVector3Int.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d785fb8b4b7840cda784710106feb220 3 | timeCreated: 1692081990 -------------------------------------------------------------------------------- /Types/Reorderable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | 6 | namespace MyBox 7 | { 8 | #region Default Reordable Types 9 | 10 | [Serializable] 11 | public class ReorderableGameObject : Reorderable 12 | { 13 | } 14 | 15 | [Serializable] 16 | public class ReorderableGameObjectList : ReorderableList 17 | { 18 | } 19 | 20 | [Serializable] 21 | public class ReorderableTransform : Reorderable 22 | { 23 | } 24 | 25 | [Serializable] 26 | public class ReorderableTransformList : ReorderableList 27 | { 28 | } 29 | 30 | #endregion 31 | 32 | 33 | [Serializable] 34 | public class Reorderable : Internal.ReorderableBase 35 | { 36 | public T[] Collection; 37 | 38 | public int Length 39 | { 40 | get { return Collection.Length; } 41 | } 42 | 43 | public T this[int i] 44 | { 45 | get { return Collection[i]; } 46 | set { Collection[i] = value; } 47 | } 48 | } 49 | 50 | [Serializable] 51 | public class ReorderableList : Internal.ReorderableBase 52 | { 53 | public List Collection; 54 | } 55 | } 56 | 57 | namespace MyBox.Internal 58 | { 59 | [Serializable] 60 | public class ReorderableBase 61 | { 62 | } 63 | } 64 | 65 | 66 | #if UNITY_EDITOR 67 | namespace MyBox.Internal 68 | { 69 | using UnityEditor; 70 | using EditorTools; 71 | 72 | [CustomPropertyDrawer(typeof(ReorderableBase), true)] 73 | public class ReorderableTypePropertyDrawer : PropertyDrawer 74 | { 75 | private ReorderableCollection _reorderable; 76 | 77 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 78 | { 79 | if (_reorderable == null) 80 | _reorderable = new ReorderableCollection(property.FindPropertyRelative("Collection"), true, true, property.displayName); 81 | 82 | return _reorderable != null ? _reorderable.Height : base.GetPropertyHeight(property, label); 83 | } 84 | 85 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 86 | { 87 | EditorGUI.BeginProperty(position, label, property); 88 | _reorderable.Draw(position); 89 | EditorGUI.EndProperty(); 90 | } 91 | } 92 | } 93 | #endif -------------------------------------------------------------------------------- /Types/Reorderable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 71b797569ec34154eb0e4d43c0225702 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/SceneReference.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a01c2dc505e0ab341958183247f3629c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/Singleton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace MyBox 5 | { 6 | public abstract class Singleton : MonoBehaviour where T : MonoBehaviour 7 | { 8 | public static T Instance 9 | { 10 | get 11 | { 12 | if (_instance == null) _instance = FindObjectOfType(); 13 | if (_instance == null) Debug.LogError("Singleton of type : " + typeof(T).Name + " not found on scene"); 14 | 15 | return _instance; 16 | } 17 | } 18 | private static T _instance; 19 | 20 | 21 | /// 22 | /// Use this function to cache instance and destroy duplicate objects. 23 | /// Also use DontDestroyOnLoad if "persistent" is not set to false 24 | /// 25 | protected void InitializeSingleton(bool persistent = true) 26 | { 27 | if (_instance == null) 28 | { 29 | _instance = (T)Convert.ChangeType(this, typeof(T)); 30 | if (persistent) DontDestroyOnLoad(_instance); 31 | } 32 | else 33 | { 34 | Debug.LogWarning($"Another instance of Singleton<{typeof(T).Name}> detected on GO {name}. Destroyed", gameObject); 35 | Destroy(this); 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Types/Singleton.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 025d12ecdfafc224fa43b83186bee3cf 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Types/StateOnAwake.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | public class StateOnAwake : MonoBehaviour 6 | { 7 | public bool Active; 8 | public GameObject TargetObject; 9 | public Renderer TargetComponent; 10 | 11 | private void Awake() 12 | { 13 | if (TargetObject != null) TargetObject.SetActive(Active); 14 | if (TargetComponent != null) 15 | { 16 | //TODO: enabled field through reflection..? Renderer is not a behaviour -_- 17 | TargetComponent.enabled = Active; 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Types/StateOnAwake.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed62496e85434631a8ce8752f246de34 3 | timeCreated: 1551189906 -------------------------------------------------------------------------------- /Types/TransformData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9ae02742dde3480e889abc9bb61dc897 3 | timeCreated: 1605955399 -------------------------------------------------------------------------------- /Types/UIFollow.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace MyBox 4 | { 5 | /// 6 | /// Used on object with RectTransform to follow Transform on the scene 7 | /// 8 | [ExecuteInEditMode] 9 | public class UIFollow : MonoBehaviour 10 | { 11 | public Transform ToFollow; 12 | /// 13 | /// Follow Offset in Units 14 | /// 15 | public Vector2 Offset; 16 | /// 17 | /// Used Camera (Camera.main by default) 18 | /// 19 | public Camera GameCamera; 20 | 21 | #pragma warning disable 0649 22 | [SerializeField, Tooltip("Hide Canvas when Following Panel is offscreen")] 23 | private bool _hideOffscreen; 24 | #pragma warning restore 0649 25 | [SerializeField, ConditionalField("_hideOffscreen")] 26 | private Canvas _canvas; 27 | 28 | [SerializeField] private bool _editTime = true; 29 | 30 | 31 | public bool IsOffscreen => OffscreenOffset != Vector2.zero; 32 | 33 | private RectTransform Transform => _transform ? _transform : _transform = transform as RectTransform; 34 | private RectTransform _transform; 35 | 36 | public Vector2 OffscreenOffset 37 | { 38 | get 39 | { 40 | var rect = Transform.rect; 41 | 42 | var halfWidth = rect.width / 2; 43 | var offX = 0f; 44 | var anchoredPosition = Transform.anchoredPosition; 45 | var minX = anchoredPosition.x + halfWidth; 46 | var maxX = anchoredPosition.x - halfWidth - Screen.width; 47 | if (minX < 0) offX = minX; 48 | else if (maxX > 0) offX = maxX; 49 | 50 | var halfHeight = rect.height / 2; 51 | var offY = 0f; 52 | var minY = anchoredPosition.y + halfHeight; 53 | var maxY = anchoredPosition.y - halfHeight - Screen.height; 54 | if (minY < 0) offY = minY; 55 | else if (maxY > 0) offY = maxY; 56 | return new Vector2(offX, offY); 57 | } 58 | } 59 | 60 | 61 | private void LateUpdate() 62 | { 63 | if (!_editTime && !Application.isPlaying) return; 64 | 65 | if (ToFollow == null) return; 66 | if (GameCamera == null) 67 | { 68 | GameCamera = Camera.main; 69 | if (GameCamera == null) 70 | { 71 | WarningsPool.LogWarning(name + ".UIFollow Caused: Main Camera not found. Assign Camera manually", this); 72 | return; 73 | } 74 | } 75 | 76 | Transform.anchorMax = Vector2.zero; 77 | Transform.anchorMin = Vector2.zero; 78 | 79 | var followPosition = ToFollow.position.Offset(Offset); 80 | Vector3 screenspace = GameCamera.WorldToScreenPoint(followPosition); 81 | Transform.anchoredPosition = screenspace; 82 | 83 | ToggleCanvasOffscreen(); 84 | } 85 | 86 | private void ToggleCanvasOffscreen() 87 | { 88 | if (!_hideOffscreen) return; 89 | _canvas.enabled = !IsOffscreen; 90 | } 91 | 92 | #if UNITY_EDITOR 93 | private void OnValidate() 94 | { 95 | if (_hideOffscreen && _canvas == null) 96 | { 97 | _canvas = GetComponentInChildren(); 98 | if (_canvas == null) _canvas = GetComponentInParent(); 99 | 100 | Debug.LogError(name + " Caused: UIFollow with HideOffscreen cant found Canvas"); 101 | } 102 | } 103 | #endif 104 | } 105 | } -------------------------------------------------------------------------------- /Types/UIFollow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 82cf416578b148d9ae86cde7de85a237 3 | timeCreated: 1539765575 -------------------------------------------------------------------------------- /Types/UIImageBasedButton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using UnityEngine.EventSystems; 4 | using UnityEngine.UI; 5 | 6 | namespace MyBox 7 | { 8 | [RequireComponent(typeof(Button), typeof(Image))] 9 | public class UIImageBasedButton : MonoBehaviour, ISelectHandler, IDeselectHandler, IPointerEnterHandler, IPointerExitHandler 10 | { 11 | #pragma warning disable 0649 12 | [SerializeField, MustBeAssigned] private Sprite _regularSprite; 13 | [SerializeField, MustBeAssigned] private Sprite _regularSelectedSprite; 14 | [SerializeField, MustBeAssigned] private Sprite _clickedSprite; 15 | [SerializeField, MustBeAssigned] private Sprite _clickedSelectedSprite; 16 | #pragma warning restore 0649 17 | 18 | public Action OnToggled; 19 | 20 | public bool AlternativeSpriteset 21 | { 22 | get => _alternative; 23 | set => _alternative = value; 24 | } 25 | 26 | private bool _alternative; 27 | private bool _selected; 28 | private Image _image; 29 | private Button _button; 30 | 31 | 32 | private void Awake() 33 | { 34 | _image = GetComponent(); 35 | _button = GetComponent