SW 중심대학 OSS GIT 서버 박건태, 이승준, 고기완, 이준호 새로운 배포
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
7.8 KiB

4 years ago
  1. #if UNITY_IOS
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using System.Xml;
  9. using UnityEditor;
  10. using UnityEditor.Build;
  11. using UnityEditor.Build.Reporting;
  12. using UnityEditor.Callbacks;
  13. using UnityEditor.iOS.Xcode;
  14. using UnityEditor.Rendering;
  15. using UnityEditor.XR.ARSubsystems;
  16. using UnityEngine;
  17. using UnityEngine.Rendering;
  18. using UnityEngine.XR.ARSubsystems;
  19. using UnityEngine.XR.ARKit;
  20. using OSVersion = UnityEngine.XR.ARKit.OSVersion;
  21. namespace UnityEditor.XR.ARKit
  22. {
  23. internal class ARKitBuildProcessor
  24. {
  25. public static IEnumerable<T> AssetsOfType<T>() where T : UnityEngine.Object
  26. {
  27. foreach(var guid in AssetDatabase.FindAssets("t:" + typeof(T).Name))
  28. {
  29. var path = AssetDatabase.GUIDToAssetPath(guid);
  30. yield return AssetDatabase.LoadAssetAtPath<T>(path);
  31. }
  32. }
  33. class PostProcessor : IPostprocessBuildWithReport
  34. {
  35. public int callbackOrder { get { return 0; } }
  36. public void OnPostprocessBuild(BuildReport report)
  37. {
  38. if (report.summary.platform != BuildTarget.iOS)
  39. {
  40. return;
  41. }
  42. BuildHelper.RemoveShaderFromProject(ARKitCameraSubsystem.backgroundShaderName);
  43. HandleARKitRequiredFlag(report.summary.outputPath);
  44. }
  45. static void HandleARKitRequiredFlag(string pathToBuiltProject)
  46. {
  47. var arkitSettings = ARKitSettings.GetOrCreateSettings();
  48. string plistPath = Path.Combine(pathToBuiltProject, "Info.plist");
  49. PlistDocument plist = new PlistDocument();
  50. plist.ReadFromString(File.ReadAllText(plistPath));
  51. PlistElementDict rootDict = plist.root;
  52. // Get or create array to manage device capabilities
  53. const string capsKey = "UIRequiredDeviceCapabilities";
  54. PlistElementArray capsArray;
  55. PlistElement pel;
  56. if (rootDict.values.TryGetValue(capsKey, out pel))
  57. {
  58. capsArray = pel.AsArray();
  59. }
  60. else
  61. {
  62. capsArray = rootDict.CreateArray(capsKey);
  63. }
  64. // Remove any existing "arkit" plist entries
  65. const string arkitStr = "arkit";
  66. capsArray.values.RemoveAll(x => arkitStr.Equals(x.AsString()));
  67. if (arkitSettings.requirement == ARKitSettings.Requirement.Required)
  68. {
  69. // Add "arkit" plist entry
  70. capsArray.AddString(arkitStr);
  71. }
  72. File.WriteAllText(plistPath, plist.WriteToString());
  73. }
  74. }
  75. class Preprocessor : IPreprocessBuildWithReport, IPreprocessShaders
  76. {
  77. // Magic value according to
  78. // https://docs.unity3d.com/ScriptReference/PlayerSettings.GetArchitecture.html
  79. // "0 - None, 1 - ARM64, 2 - Universal."
  80. const int k_TargetArchitectureArm64 = 1;
  81. const int k_TargetArchitectureUniversal = 2;
  82. void SelectStaticLib()
  83. {
  84. const string pluginPath = "Packages/com.unity.xr.arkit/Runtime/iOS";
  85. LibUtil.SelectPlugin(
  86. PluginImporter.GetAtPath($"{pluginPath}/Xcode1000/UnityARKit.a") as PluginImporter,
  87. PluginImporter.GetAtPath($"{pluginPath}/Xcode1100/UnityARKit.a") as PluginImporter);
  88. }
  89. public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> data)
  90. {
  91. // Remove shader variants for the camera background shader that will fail compilation because of package dependencies.
  92. string backgroundShaderName = ARKitCameraSubsystem.backgroundShaderName;
  93. if (backgroundShaderName.Equals(shader.name))
  94. {
  95. foreach (var backgroundShaderKeywordToNotCompile in ARKitCameraSubsystem.backgroundShaderKeywordsToNotCompile)
  96. {
  97. ShaderKeyword shaderKeywordToNotCompile = new ShaderKeyword(shader, backgroundShaderKeywordToNotCompile);
  98. for (int i = (data.Count - 1); i >= 0; --i)
  99. {
  100. if (data[i].shaderKeywordSet.IsEnabled(shaderKeywordToNotCompile))
  101. {
  102. data.RemoveAt(i);
  103. }
  104. }
  105. }
  106. }
  107. }
  108. public void OnPreprocessBuild(BuildReport report)
  109. {
  110. if (report.summary.platform != BuildTarget.iOS)
  111. return;
  112. if (string.IsNullOrEmpty(PlayerSettings.iOS.cameraUsageDescription))
  113. throw new BuildFailedException("ARKit requires a Camera Usage Description (Player Settings > iOS > Other Settings > Camera Usage Description)");
  114. SelectStaticLib();
  115. EnsureMetalIsFirstApi();
  116. if(ARKitSettings.GetOrCreateSettings().requirement == ARKitSettings.Requirement.Required)
  117. {
  118. EnsureMinimumBuildTarget();
  119. EnsureTargetArchitecturesAreSupported(report.summary.platformGroup);
  120. }
  121. else if (PlayerSettings.GetArchitecture(report.summary.platformGroup) == k_TargetArchitectureUniversal)
  122. {
  123. EnsureOpenGLIsUsed();
  124. }
  125. BuildHelper.AddBackgroundShaderToProject(ARKitCameraSubsystem.backgroundShaderName);
  126. }
  127. void EnsureMinimumBuildTarget()
  128. {
  129. var userSetTargetVersion = OSVersion.Parse(PlayerSettings.iOS.targetOSVersionString);
  130. if (userSetTargetVersion < new OSVersion(11))
  131. {
  132. throw new BuildFailedException("You have selected a minimum target iOS version of " + userSetTargetVersion + " and have the ARKit package installed. "
  133. + "ARKit requires at least iOS version 11.0 (See Player Settings > Other Settings > Target minimum iOS Version).");
  134. }
  135. }
  136. void EnsureTargetArchitecturesAreSupported(BuildTargetGroup buildTargetGroup)
  137. {
  138. if (PlayerSettings.GetArchitecture(buildTargetGroup) != k_TargetArchitectureArm64)
  139. throw new BuildFailedException("ARKit XR Plugin only supports the ARM64 architecture. See Player Settings > Other Settings > Architecture.");
  140. }
  141. void EnsureMetalIsFirstApi()
  142. {
  143. var graphicsApis = PlayerSettings.GetGraphicsAPIs(BuildTarget.iOS);
  144. if (graphicsApis.Length > 0)
  145. {
  146. var graphicsApi = graphicsApis[0];
  147. if (graphicsApi != GraphicsDeviceType.Metal)
  148. throw new BuildFailedException($"You currently have {graphicsApi} at the top of the list of Graphics APis. However, Metal needs to be first in the list. (See Player Settings > Other Settings > Graphics APIs)");
  149. }
  150. }
  151. void EnsureOpenGLIsUsed()
  152. {
  153. var graphicsApis = PlayerSettings.GetGraphicsAPIs(BuildTarget.iOS);
  154. if (graphicsApis.Length > 0)
  155. {
  156. if(!graphicsApis.Contains(GraphicsDeviceType.OpenGLES2))
  157. throw new BuildFailedException("To build for 'Universal' architecture, OpenGLES2 is needed. (See Player Settings > Other Settings > Graphics APIs)");
  158. }
  159. }
  160. public int callbackOrder { get { return 0; } }
  161. }
  162. }
  163. }
  164. #endif