ARKitReferenceObjectLibraryBuildProcessor.cs
6.31 KB
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#if UNITY_IOS
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using UnityEngine;
using UnityEngine.XR.ARKit;
using UnityEngine.XR.ARSubsystems;
namespace UnityEditor.XR.ARKit
{
static class ARKitReferenceObjectLibraryBuildProcessor
{
[Flags]
enum Warnings
{
None = 0,
MissingEntry = 1 << 0,
EmptyLibrary = 1 << 1,
MissingName = 1 << 2,
All =
MissingEntry |
EmptyLibrary |
MissingName
}
static IEnumerable<ARResourceGroup> ResourceGroups(Warnings warnings)
{
foreach (var library in ARKitBuildProcessor.AssetsOfType<XRReferenceObjectLibrary>())
{
// Create a resource group for each reference object library
var resourceGroup = new ARResourceGroup(library.name + "_" + library.guid.ToUUIDString());
int resourceCount = 0;
foreach (var referenceObject in library)
{
if (string.IsNullOrEmpty(referenceObject.name) && (warnings & Warnings.MissingName) != 0)
{
Debug.LogWarningFormat("Reference object {0} named '{1}' in library {2} does not have a name. The reference object will still work, but you will not be able to refer to it by name.",
library.indexOf(referenceObject), referenceObject.name, AssetDatabase.GetAssetPath(library));
}
var arkitEntry = referenceObject.FindEntry<ARKitReferenceObjectEntry>();
if (arkitEntry == null)
{
if ((warnings & Warnings.MissingEntry) != 0)
{
Debug.LogWarningFormat("The ARKit variant for reference object {0} named '{1}' in library {2} is missing. This reference object will omitted from the library.",
library.indexOf(referenceObject), referenceObject.name, AssetDatabase.GetAssetPath(library));
}
}
else
{
try
{
resourceGroup.AddResource(new ARReferenceObject(referenceObject, arkitEntry));
resourceCount++;
}
catch (ARReferenceObject.InvalidAssetPathException)
{
throw new BuildFailedException(string.Format(
"The ARKit variant for reference object {0} named '{1}' in reference object library {2} does not refer to a valid asset file.",
library.indexOf(referenceObject), referenceObject.name, AssetDatabase.GetAssetPath(library)));
}
catch (ARReferenceObject.MissingMetadataException)
{
throw new BuildFailedException(string.Format(
"The ARKit variant for reference object {0} named '{1}' in reference object library {2} could not be read. The arobject file may be corrupt.",
library.indexOf(referenceObject), referenceObject.name, AssetDatabase.GetAssetPath(library)));
}
catch (ARReferenceObject.MissingTrackingDataException)
{
throw new BuildFailedException(string.Format(
"The ARKit variant for reference object {0} named '{1}' in reference object library {2} is missing tracking data (the 3D object scan data). The arobject file may be corrupt.",
library.indexOf(referenceObject), referenceObject.name, AssetDatabase.GetAssetPath(library)));
}
}
}
if ((resourceCount == 0) && (warnings & Warnings.EmptyLibrary) != 0)
{
Debug.LogWarningFormat("Reference object library at {0} does not contain any ARKit reference objects. The library will be empty.",
AssetDatabase.GetAssetPath(library));
}
yield return resourceGroup;
}
}
class Preprocessor : IPreprocessBuildWithReport
{
public int callbackOrder { get { return 1; } }
// Validates the ARKit reference objects
public void OnPreprocessBuild(BuildReport report)
{
if (report.summary.platform != BuildTarget.iOS)
return;
foreach (var resourceGroup in ResourceGroups(Warnings.None))
{
// Generating a resource group will throw exceptions
// if any of the reference objects are invalid.
}
}
}
class Postprocessor : IPostprocessBuildWithReport
{
public int callbackOrder { get { return 1; } }
public void OnPostprocessBuild(BuildReport report)
{
if (report.summary.platform != BuildTarget.iOS)
return;
var buildOutputPath = report.summary.outputPath;
// Read in the Xcode project
var pbxProjectPath = PBXProject.GetPBXProjectPath(buildOutputPath);
var pbxProject = new PBXProject();
pbxProject.ReadFromString(File.ReadAllText(pbxProjectPath));
// Create a new asset catalog
var assetCatalog = new XcodeAssetCatalog("ARReferenceObjects");
// Create a resource group for each reference object set
foreach (var resourceGroup in ResourceGroups(Warnings.All))
{
assetCatalog.AddResourceGroup(resourceGroup);
}
// Write the asset catalog to disk
assetCatalog.WriteAndAddToPBXProject(pbxProject, buildOutputPath);
// Write out the updated Xcode project
File.WriteAllText(pbxProjectPath, pbxProject.WriteToString());
}
}
}
}
#endif