Skip to content

Commit 22de986

Browse files
committed
Build Resources.FindObjectsOfTypeAll bugfix
1 parent 6bc1626 commit 22de986

File tree

3 files changed

+68
-31
lines changed

3 files changed

+68
-31
lines changed

Editor/Build/MetadataLookupBuild.cs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
1-
using UnityEditor;
1+
using System;
2+
using System.Collections.Generic;
3+
using UnityEditor;
24
using UnityEditor.Build;
35
using UnityEditor.Build.Reporting;
46
using UnityEngine;
57

68
// This is a bit of a hack, but we need to ensure that our metadata is not stripped on build,
7-
// so at build time we clone them into a temporary resources directory. Afterwards we delete the directory.
8-
// Cloning works since each metadata object holds a reference to the thing it belongs to and we can
9-
// just use the clone at runtime instead.
9+
// so at build time we clone them into a temporary resources directory. Cloning works since
10+
// each metadata object holds a reference to the thing it belongs to and we can just use the
11+
// clone at runtime instead. After we've created the build we delete the directory.
1012
public class MetadataLookupPreprocessBuild : IPreprocessBuildWithReport
1113
{
1214
public int callbackOrder { get { return 0; } }
1315

1416
public static bool HadResourcesDirectory = false;
1517

18+
CustomAssetMetadata CloneCustomAssetMetadata(CustomAssetMetadata assetMetadata, string basePath, ref int index)
19+
{
20+
var clone = UnityEngine.Object.Instantiate(assetMetadata);
21+
var name = $"{assetMetadata.GetInstanceID()}-{index}"; index++;
22+
AssetDatabase.CreateAsset(clone, $"{basePath}/{name}.asset");
23+
return clone;
24+
}
25+
1626
public void OnPreprocessBuild(BuildReport report)
1727
{
1828
const string basePath = "Assets/Resources/" + MetadataLookup.kResourcePath;
@@ -22,17 +32,34 @@ public void OnPreprocessBuild(BuildReport report)
2232
System.IO.Directory.Delete(basePath, true);
2333
System.IO.Directory.CreateDirectory(basePath);
2434
var list = ScriptableObject.CreateInstance<MetadataLookupAsset>();
25-
var allMetadata = Resources.FindObjectsOfTypeAll<CustomAssetMetadata>();
35+
36+
var allMetadata = new List<CustomAssetMetadata>();
37+
38+
var allPaths = UnityEditor.AssetDatabase.FindAssets($"t:Material"); // TODO: support more than just materials
39+
foreach(var assetPath in allPaths)
40+
{
41+
foreach (var item in UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath))
42+
{
43+
if (item is not CustomAssetMetadata metadata)
44+
continue;
45+
allMetadata.Add(metadata);
46+
}
47+
UnityEditor.EditorUtility.UnloadUnusedAssetsImmediate();
48+
}
49+
50+
// This doesn't work since Resources.FindObjectsOfTypeAll only works on
51+
// assets currently loaded into memory.
52+
//allMetadata.AddRange(Resources.FindObjectsOfTypeAll<CustomAssetMetadata>());
53+
2654
int index = 0;
27-
for (int i = 0; i < allMetadata.Length; i++)
28-
{
29-
var clone = UnityEngine.Object.Instantiate(allMetadata[i]);
30-
var name = $"{allMetadata[i].GetInstanceID()}-{index}"; index++;
31-
AssetDatabase.CreateAsset(clone, $"{basePath}/{name}.asset");
32-
allMetadata[i] = clone;
55+
for (int i = 0; i < allMetadata.Count; i++)
56+
{
57+
allMetadata[i] = CloneCustomAssetMetadata(allMetadata[i], basePath, ref index);
3358
}
34-
list.allMetadata = allMetadata;
35-
AssetDatabase.CreateAsset(list, $"{basePath}/{MetadataLookup.kAssetName}.asset");
59+
UnityEditor.EditorUtility.UnloadUnusedAssetsImmediate();
60+
61+
list.allMetadata = allMetadata.ToArray();
62+
AssetDatabase.CreateAsset(list, $"{basePath}/{MetadataLookup.kAssetName}.asset");
3663
AssetDatabase.StopAssetEditing();
3764
}
3865

Runtime/Common/MetadataLookup.cs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-

1+
22
#if !UNITY_EDITOR
33
#define UNITY_RUNTIME
44
#endif
5+
using System;
56
using System.Collections.Generic;
67
using System.Runtime.CompilerServices;
78
using UnityEngine;
89

910
internal static class MetadataLookup
1011
{
11-
public const string kResourcePath = "AssetMetadata";
12+
public const string kResourcePath = "__AssetMetadata";
1213
public const string kAssetName = "list.asset";
1314

1415
readonly static Dictionary<int, List<CustomAssetMetadata>> table = new();
@@ -110,7 +111,7 @@ internal static bool Register(UnityEngine.LazyLoadReference<UnityEngine.Object>
110111
internal static void Unregister(UnityEngine.LazyLoadReference<UnityEngine.Object> reference, CustomAssetMetadata metadata)
111112
{
112113
if (reference.isBroken || !reference.isSet ||
113-
object.ReferenceEquals(metadata, null))
114+
object.ReferenceEquals(metadata, null))
114115
return;
115116

116117
if (!table.TryGetValue(reference.instanceID, out var metadataList))
@@ -119,7 +120,7 @@ internal static void Unregister(UnityEngine.LazyLoadReference<UnityEngine.Object
119120
metadataList.Remove(metadata);
120121
if (metadataList.Count == 0)
121122
{
122-
table.Remove(reference.instanceID);
123+
table.Remove(reference.instanceID);
123124
}
124125
}
125126

@@ -130,32 +131,41 @@ static bool RegisterMetadataForAsset(string assetPath)
130131
return false;
131132

132133
bool foundAny = false;
133-
foreach (var item in UnityEditor.AssetDatabase.LoadAllAssetsAtPath(assetPath))
134+
var subAssets = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath);
135+
foreach (var item in subAssets)
134136
{
135137
if (item is not CustomAssetMetadata metadata)
136138
continue;
137139

138140
foundAny = MetadataLookup.Register(metadata.reference.asset, metadata) || foundAny;
139141
}
142+
UnityEditor.EditorUtility.UnloadUnusedAssetsImmediate();
140143
return foundAny;
141144
}
142145
#endif
143146

144147
static bool GetAllMetadataForAsset(UnityEngine.Object asset, out List<CustomAssetMetadata> result)
145148
{
146-
EnsureInitialized();
147-
if (table.TryGetValue(asset.GetInstanceID(), out result))
148-
return true;
149+
if (asset)
150+
{
151+
EnsureInitialized();
152+
if (table.TryGetValue(asset.GetInstanceID(), out result))
153+
return true;
149154
#if UNITY_EDITOR
150-
if (Application.isEditor)
151-
{
152-
var assetPath = UnityEditor.AssetDatabase.GetAssetPath(asset);
153-
RegisterMetadataForAsset(assetPath);
154-
if (table.TryGetValue(asset.GetInstanceID(), out result))
155-
return true;
156-
}
155+
if (Application.isEditor)
156+
{
157+
var assetPath = UnityEditor.AssetDatabase.GetAssetPath(asset);
158+
if (!RegisterMetadataForAsset(assetPath))
159+
{
160+
result = null;
161+
return false;
162+
}
163+
if (table.TryGetValue(asset.GetInstanceID(), out result))
164+
return true;
165+
}
157166
#endif
158-
result = null;
167+
}
168+
result = null;
159169
return false;
160170
}
161171

@@ -192,7 +202,7 @@ static void InitializeEditor()
192202
var allMetadata = Resources.FindObjectsOfTypeAll<CustomAssetMetadata>();
193203
foreach (var metadata in allMetadata)
194204
{
195-
if (metadata != null)
205+
if (!metadata)
196206
continue;
197207
var assetPath = UnityEditor.AssetDatabase.GetAssetPath(metadata);
198208
RegisterMetadataForAsset(assetPath);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "com.custom_asset_metadata",
33
"displayName": "Custom Asset Metadata",
4-
"version": "1.2.1",
4+
"version": "1.2.2",
55
"unity": "2020.3",
66
"description": "Adds the ability to store meta data on Assets",
77
"license": "MIT",

0 commit comments

Comments
 (0)