This repository has been archived by the owner on Jan 18, 2022. It is now read-only.
/
PrefabPreprocessor.cs
107 lines (93 loc) · 3.58 KB
/
PrefabPreprocessor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Improbable.Gdk.Subscriptions.Editor
{
/// <summary>
/// A prefab processor which disables any Monobehaviours on top-level GameObjects in the Resources folder
/// which have fields with the <see cref="RequireAttribute"/> on them.
/// </summary>
/// <remarks>
/// This processes the prefabs when you build or when you press play in the Unity Editor.
/// </remarks>
[InitializeOnLoad]
public class PrefabPreprocessor : IPreprocessBuildWithReport
{
// Needed for IPreprocessBuildWithReport
public int callbackOrder => 0;
static PrefabPreprocessor()
{
EditorApplication.playModeStateChanged += OnPlaymodeStateChanged;
}
void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report)
{
PreprocessPrefabs();
}
private static void OnPlaymodeStateChanged(PlayModeStateChange playModeStateChange)
{
if (playModeStateChange == PlayModeStateChange.ExitingEditMode)
{
PreprocessPrefabs();
}
}
private static void PreprocessPrefabs()
{
var allPrefabObjectsInResources = AssetDatabase.FindAssets("t:Prefab")
.Select(AssetDatabase.GUIDToAssetPath)
.Where(assetPath => assetPath.Contains("Resources")).ToArray();
AssetDatabase.StartAssetEditing();
foreach (var prefabPath in allPrefabObjectsInResources)
{
try
{
var prefabObject = PrefabUtility.LoadPrefabContents(prefabPath);
if (prefabObject == null)
{
continue;
}
var changed = false;
foreach (var monoBehaviour in prefabObject
.GetComponents<MonoBehaviour>()
.Where(DoesBehaviourNeedFixing))
{
monoBehaviour.enabled = false;
changed = true;
}
if (changed)
{
PrefabUtility.SaveAsPrefabAsset(prefabObject, prefabPath);
}
PrefabUtility.UnloadPrefabContents(prefabObject);
}
catch
{
Debug.LogError($"Failed to process prefab {prefabPath}");
throw;
}
}
AssetDatabase.StopAssetEditing();
}
private static bool IsBehaviourEnabledInEditor(Object obj)
{
return !ReferenceEquals(obj, null) && EditorUtility.GetObjectEnabled(obj) == 1;
}
private static bool DoesBehaviourNeedConditionalEnabling(Type targetType)
{
return
targetType.GetCustomAttribute<WorkerTypeAttribute>() != null ||
targetType
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
.Any(field => Attribute.IsDefined(field, typeof(RequireAttribute), false));
}
private static bool DoesBehaviourNeedFixing(MonoBehaviour monoBehaviour)
{
return IsBehaviourEnabledInEditor(monoBehaviour) &&
DoesBehaviourNeedConditionalEnabling(monoBehaviour.GetType());
}
}
}