├── .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