Skip to content

Commit

Permalink
bugfix: MustBeAssigned won't be triggered for prefab assets
Browse files Browse the repository at this point in the history
  • Loading branch information
Deadcows committed Aug 17, 2021
1 parent 4c140e9 commit 54cdd78
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 7 deletions.
1 change: 1 addition & 0 deletions Attributes/AutoPropertyAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ static AutoPropertyHandler()
PrefabStage.prefabStageOpened += stage => CheckComponentsInPrefab(stage.prefabContentsRoot);
}

// TODO: GetFieldsWithAttribute is slow, should be optimized
private static void CheckAssets() => MyEditor
.GetFieldsWithAttribute<AutoPropertyAttribute>()
.ForEach(FillProperty);
Expand Down
15 changes: 11 additions & 4 deletions Attributes/MustBeAssignedAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,33 @@ static MustBeAssignedAttributeChecker()
}

private static void AssertComponentsInScene()
{
AssertComponent(MyEditor.GetAllUnityObjects());
{
//TODO: Optimize here, we need to check only instantiated behaviours AND ScriptableObject assets
AssertComponent(MyEditor.GetAllUnityObjects(), true);
}

private static void AssertComponentsInPrefab(GameObject prefab)
{
MonoBehaviour[] components = prefab.GetComponentsInChildren<MonoBehaviour>();
AssertComponent(components);
// ReSharper disable once CoVariantArrayConversion
AssertComponent(components, false);
}

private static void AssertComponent(UnityEngine.Object[] objects)
private static void AssertComponent(UnityEngine.Object[] objects, bool excludePrefabs)
{
foreach (var obj in objects)
{
if (obj == null) continue;
if (!(obj.Is<MonoBehaviour>() || obj.Is<ScriptableObject>())) continue;

Type typeOfScript = obj.GetType();
FieldInfo[] mustBeAssignedFields = typeOfScript
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Where(field => field.IsDefined(typeof(MustBeAssignedAttribute), false)).ToArray();
if (mustBeAssignedFields.IsNullOrEmpty()) continue;

if (excludePrefabs && PrefabUtility.IsPartOfPrefabAsset(obj)) continue;

foreach (FieldInfo field in mustBeAssignedFields)
{
object propValue = field.GetValue(obj);
Expand Down
7 changes: 4 additions & 3 deletions Extensions/EditorExtensions/MyEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,11 @@ private static GUIContent[] GetTextures(string baseName, string postFix, int sta
/// Get all fields with specified attribute on all Unity Objects
/// </summary>
public static IEnumerable<ObjectField> GetFieldsWithAttribute<T>(
GameObject prefab = null) where T : Attribute
GameObject parent = null) where T : Attribute
{
var allObjects = prefab == null ?
var allObjects = parent == null ?
GetAllUnityObjects() :
prefab.GetComponentsInChildren<MonoBehaviour>();
parent.GetComponentsInChildren<MonoBehaviour>();
return allObjects.Where(obj => obj != null)
.SelectMany(obj => obj.GetType()
.GetFields(BindingFlags.Public
Expand Down Expand Up @@ -214,6 +214,7 @@ public ObjectField(FieldInfo field, Object context)
/// </summary>
public static Object[] GetAllUnityObjects()
{
// TODO: First call after Domain Reload is extremely slow, should be optimized
LoadAllAssetsOfType(typeof(ScriptableObject));
LoadAllAssetsOfType("Prefab");
return Resources.FindObjectsOfTypeAll(typeof(Object));
Expand Down

0 comments on commit 54cdd78

Please sign in to comment.