Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Deadcows/MyBox
Browse files Browse the repository at this point in the history
  • Loading branch information
Deadcows committed Sep 28, 2021
2 parents 3e57feb + de63384 commit b68f2ed
Show file tree
Hide file tree
Showing 29 changed files with 398 additions and 38 deletions.
13 changes: 8 additions & 5 deletions Attributes/AutoPropertyAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,17 +105,20 @@ public static class AutoPropertyHandler

static AutoPropertyHandler()
{
// this event is for GameObjects in the scene.
// this event is for GameObjects in the project.
MyEditorEvents.OnSave += CheckAssets;
// this event is for prefabs saved in edit mode.
PrefabStage.prefabSaved += CheckComponentsInPrefab;
PrefabStage.prefabStageOpened += stage => CheckComponentsInPrefab(stage.prefabContentsRoot);
}

// TODO: GetFieldsWithAttribute is slow, should be optimized
private static void CheckAssets() => MyEditor
.GetFieldsWithAttribute<AutoPropertyAttribute>()
.ForEach(FillProperty);
private static void CheckAssets()
{
var toFill = MyBoxSettings.EnableSOCheck ?
MyEditor.GetFieldsWithAttributeFromAll<AutoPropertyAttribute>() :
MyEditor.GetFieldsWithAttributeFromScenes<AutoPropertyAttribute>();
toFill.ForEach(FillProperty);
}

private static void CheckComponentsInPrefab(GameObject prefab) => MyEditor
.GetFieldsWithAttribute<AutoPropertyAttribute>(prefab)
Expand Down
14 changes: 8 additions & 6 deletions Attributes/MustBeAssignedAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,16 @@ static MustBeAssignedAttributeChecker()

private static void AssertComponentsInScene()
{
var behaviours = Object.FindObjectsOfType<MonoBehaviour>();
var behaviours = Object.FindObjectsOfType<MonoBehaviour>(true);
// ReSharper disable once CoVariantArrayConversion
AssertComponents(behaviours);

// TODO: Allow to disable SO check
var scriptableObjects = MyScriptableObject.LoadAssets<ScriptableObject>();
// ReSharper disable once CoVariantArrayConversion
AssertComponents(scriptableObjects);

if (MyBoxSettings.EnableSOCheck)
{
var scriptableObjects = MyScriptableObject.LoadAssets<ScriptableObject>();
// ReSharper disable once CoVariantArrayConversion
AssertComponents(scriptableObjects);
}
}

private static void AssertComponentsInPrefab(GameObject prefab)
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ All notable changes to this package will be documented in this file.
- Breaking Changes: MinMaxFloat.RandomInRangeInclusive was redundant, removed
- Breaking Changes: Extension IList.GetRandomCollection is removed, replaced with IList.ExclusiveSample
- Breaking Changes: Removed bunch of methods from MyPhysics class
TODO Docs - Added: Ability to disable performant features of MyBox in MyBox Window
TODO Docs - Added: PlayerPrefs and EditorPrefs Bool/Float/Int/String/Vector3 types
- Changed: ReadOnlyAttribute now might be conditional, just like ConditionalField. Thanks to @CrizGames!
- Changed: AutoProperty and MustBeAssigned attributes now work fine with ScriptableObjects! Thanks to @tonygiang for the addition!
TODO Docs - Changed: SceneAttribute is now rendered as popup list of scenes from Editor Build Settings
Expand Down
63 changes: 57 additions & 6 deletions Extensions/EditorExtensions/MyEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,43 @@ private static GUIContent[] GetTextures(string baseName, string postFix, int sta
/// <summary>
/// Get all fields with specified attribute on all Unity Objects
/// </summary>
public static List<ObjectField> GetFieldsWithAttribute<T>(GameObject parent = null) where T : Attribute
public static List<ObjectField> GetFieldsWithAttributeFromScenes<T>() where T : Attribute
{
var allObjects = parent == null ?
GetAllUnityObjects() :
parent.GetComponentsInChildren<MonoBehaviour>();
var allObjects = GetAllBehavioursInScenes();

// ReSharper disable once CoVariantArrayConversion
return GetFieldsWithAttribute<T>(allObjects);
}

/// <summary>
/// Get all fields with specified attribute on all Unity Objects
/// </summary>
public static List<ObjectField> GetFieldsWithAttributeFromAll<T>() where T : Attribute
{
var allObjects = GetAllUnityObjects();

return GetFieldsWithAttribute<T>(allObjects);
}

/// <summary>
/// Get all fields with specified attribute from Prefab Root GO
/// </summary>
public static List<ObjectField> GetFieldsWithAttribute<T>(GameObject root) where T : Attribute
{
var allObjects = root.GetComponentsInChildren<MonoBehaviour>();

// ReSharper disable once CoVariantArrayConversion
return GetFieldsWithAttribute<T>(allObjects);
}

/// <summary>
/// Get all fields with specified attribute from set of Unity Objects
/// </summary>
public static List<ObjectField> GetFieldsWithAttribute<T>(Object[] objects) where T : Attribute
{
var desiredAttribute = typeof(T);
var result = new List<ObjectField>();
foreach (var o in allObjects)
foreach (var o in objects)
{
if (o == null) continue;
var fields = o.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
Expand All @@ -195,7 +223,7 @@ public static List<ObjectField> GetFieldsWithAttribute<T>(GameObject parent = nu
public static IEnumerable<Component> GetAllComponentsInSceneOf(Object obj,
Type type)
{
GameObject contextGO = null;
GameObject contextGO;
if (obj is Component comp) contextGO = comp.gameObject;
else if (obj is GameObject go) contextGO = go;
else return Array.Empty<Component>();
Expand Down Expand Up @@ -225,6 +253,29 @@ public static Object[] GetAllUnityObjects()
LoadAllAssetsOfType("Prefab");
return Resources.FindObjectsOfTypeAll(typeof(Object));
}

/// <summary>
/// It's like FindObjectsOfType, but allows to get disabled objects
/// </summary>
public static MonoBehaviour[] GetAllBehavioursInScenes()
{
var components = new List<MonoBehaviour>();

for (var i = 0; i < SceneManager.sceneCount; i++)
{
var scene = SceneManager.GetSceneAt(i);
if (!scene.isLoaded) continue;

var root = scene.GetRootGameObjects();
foreach (var gameObject in root)
{
var behaviours = gameObject.GetComponentsInChildren<MonoBehaviour>(true);
foreach (var behaviour in behaviours) components.Add(behaviour);
}
}

return components.ToArray();
}

#endregion

Expand Down
2 changes: 2 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
* #### Add: MyDictionary, visible in inspector!!1

* #### PlayerPrefsType inspector accessibility

* #### Ability to see all objects with Commentary component on scene

* #### Add: SingleScriptableObject. No more messy Create/ with CreateAssetMenuAttribute for settings SO's
Expand Down
12 changes: 12 additions & 0 deletions Tools/Internal/MyBoxSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ public static bool PrepareOnPlaymode
}
}

public static bool EnableSOCheck
{
get => Data.EnableSOCheck;
set
{
if (Data.EnableSOCheck == value) return;
Data.EnableSOCheck = value;
SaveData(Data);
}
}

public static bool CheckForUpdates
{
get => Data.CheckForUpdates;
Expand All @@ -59,6 +70,7 @@ private class MyBoxSettingsData
public bool AutoSaveEnabled = true;
public bool CleanEmptyDirectoriesFeature;
public bool PrepareOnPlaymode = true;
public bool EnableSOCheck = true;
public bool CheckForUpdates = true;
// ReSharper restore MemberHidesStaticFromOuterClass
}
Expand Down
72 changes: 51 additions & 21 deletions Tools/Internal/MyBoxWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,33 +123,63 @@ private void OnGUI()

using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.Space(leftOffset);
MyBoxSettings.CheckForUpdates = EditorGUILayout.Toggle("Check for Updates: ", MyBoxSettings.CheckForUpdates);
GUILayout.FlexibleSpace();
}
using (new EditorGUILayout.VerticalScope())
{
using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.Space(leftOffset);
MyBoxSettings.CheckForUpdates = EditorGUILayout.Toggle("Check for Updates: ", MyBoxSettings.CheckForUpdates);
GUILayout.FlexibleSpace();
}

using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.Space(leftOffset);
MyBoxSettings.AutoSaveEnabled = EditorGUILayout.Toggle("AutoSave on Play: ", MyBoxSettings.AutoSaveEnabled);
GUILayout.FlexibleSpace();
}
using (new EditorGUILayout.HorizontalScope())
{
var label = new GUIContent("AutoSave on Play: ", "Save changes in opened scenes before Playmode. " +
"\nUnity crasher from time to time you know...");
EditorGUILayout.Space(leftOffset);
MyBoxSettings.AutoSaveEnabled = EditorGUILayout.Toggle(label, MyBoxSettings.AutoSaveEnabled);
GUILayout.FlexibleSpace();
}

using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.Space(leftOffset);
MyBoxSettings.CleanEmptyDirectoriesFeature = EditorGUILayout.Toggle("Clean Empty Folders: ", MyBoxSettings.CleanEmptyDirectoriesFeature);
GUILayout.FlexibleSpace();
}
using (new EditorGUILayout.HorizontalScope())
{
var label = new GUIContent("Clean Empty Folders: ", "Delete empty folders in project on Save. " +
"\nIt handles VCS issue with .meta files for empty folders");
EditorGUILayout.Space(leftOffset);
MyBoxSettings.CleanEmptyDirectoriesFeature = EditorGUILayout.Toggle(label, MyBoxSettings.CleanEmptyDirectoriesFeature);
GUILayout.FlexibleSpace();
}
}

using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.Space(leftOffset);
MyBoxSettings.PrepareOnPlaymode = EditorGUILayout.Toggle("Prepare on Playmode: ", MyBoxSettings.PrepareOnPlaymode);
if (GUILayout.Button(MyGUI.EditorIcons.Help, EditorStyles.label, GUILayout.Height(18)))
Application.OpenURL("https://github.com/Deadcows/MyBox/wiki/Tools-and-Features#iprepare");
EditorGUILayout.Space(80);
using (new EditorGUILayout.VerticalScope())
{
EditorGUILayout.LabelField("Performance settings", EditorStyles.miniLabel);

using (new EditorGUILayout.HorizontalScope())
{
var label = new GUIContent("Prepare on Playmode: ", "Allows to use IPrepare interface with Prepare() method called automatically." +
"\nSlightly increases project Save time.");
MyBoxSettings.PrepareOnPlaymode = EditorGUILayout.Toggle(label, MyBoxSettings.PrepareOnPlaymode);
if (GUILayout.Button(MyGUI.EditorIcons.Help, EditorStyles.label, GUILayout.Height(18)))
Application.OpenURL("https://github.com/Deadcows/MyBox/wiki/Tools-and-Features#iprepare");
GUILayout.FlexibleSpace();
}

using (new EditorGUILayout.HorizontalScope())
{
var label = new GUIContent("SO processing: ", "Allows [AutoProperty] and [MustBeAssigned] Attributes to work with Scriptable Objects." +
"\nMight increase project Save time for a few seconds.");
MyBoxSettings.EnableSOCheck = EditorGUILayout.Toggle(label, MyBoxSettings.EnableSOCheck);
GUILayout.FlexibleSpace();
}
}
GUILayout.FlexibleSpace();
}




MyGUI.DrawLine(Color.white, true);

Expand Down
21 changes: 21 additions & 0 deletions Types/EditorTypes/EditorPrefsBool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#if UNITY_EDITOR
using System;
using UnityEditor;

namespace MyBox.EditorTools
{
[Serializable]
public class EditorPrefsBool : EditorPrefsType
{
public bool Value
{
get => EditorPrefs.GetBool(Key);
set => EditorPrefs.SetBool(Key, value);
}

public EditorPrefsBool(string key) => Key = key;

public static EditorPrefsBool WithKey(string key) => new EditorPrefsBool(key);
}
}
#endif
3 changes: 3 additions & 0 deletions Types/EditorTypes/EditorPrefsBool.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions Types/EditorTypes/EditorPrefsFloat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#if UNITY_EDITOR
using System;
using UnityEditor;

namespace MyBox.EditorTools
{
[Serializable]
public class EditorPrefsFloat : EditorPrefsType
{
public float Value
{
get => EditorPrefs.GetFloat(Key, 0);
set => EditorPrefs.GetFloat(Key, value);
}

public EditorPrefsFloat(string key) => Key = key;

public static EditorPrefsFloat WithKey(string key) => new EditorPrefsFloat(key);
}
}
#endif
3 changes: 3 additions & 0 deletions Types/EditorTypes/EditorPrefsFloat.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions Types/EditorTypes/EditorPrefsString.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#if UNITY_EDITOR
using System;
using UnityEditor;

namespace MyBox.EditorTools
{
[Serializable]
public class EditorPrefsString : EditorPrefsType
{
public string Value
{
get => EditorPrefs.GetString(Key);
set => EditorPrefs.SetString(Key, value);
}

public EditorPrefsString(string key) => Key = key;

public static EditorPrefsString WithKey(string key) => new EditorPrefsString(key);
}
}
#endif
3 changes: 3 additions & 0 deletions Types/EditorTypes/EditorPrefsString.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions Types/EditorTypes/EditorPrefsType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#if UNITY_EDITOR
using System;
using UnityEditor;

namespace MyBox.EditorTools
{
[Serializable]
public class EditorPrefsType
{
public string Key { get; protected set; }

public bool IsSet => EditorPrefs.HasKey(Key);

public void Delete() => EditorPrefs.DeleteKey(Key);
}
}
#endif
3 changes: 3 additions & 0 deletions Types/EditorTypes/EditorPrefsType.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b68f2ed

Please sign in to comment.