visionOS の Enterprise API をUnityで使う時のPostProcessBuild 設定
概要
ホロラボ林です。
Apple Vision Proには 法人向けアプリのみで利用できる Enterprise APIs があります。
これらの機能はUnityアプリでも利用することができるのですが、Xcode上で行う Capability の設定をCI環境において自動化できるよう、Unity の PostProcessBuild のハマったところと、設定例を紹介します。
UnityでVisionPro開発をして、ビルド環境を構築しようとするごく少数の方向けの話です。
EnterpriseAPIについて
Enterprise APIs 自体に関しては、ホロラボメンバーが、以下の記事を書いているので、参照ください。
- Enterprise API概要の説明
- カメラアクセス機能と OpenAI API との連携の実装
Unityアプリからの利用/力こそパワー💪
Enterprise APIs の機能はUnityで開発したアプリでも利用できます。
今回は Increased performance headroom の機能をUnityアプリで利用をしたく、PostProcessBuildにて、Capabilityの設定を追加する事を試しました。
Increased performance headroom の機能はApple Vision Pro の通常のパフォーマンスでは満たすことのできない高度な処理を、Apple Vision Proが本来持っているパフォーマンスを最大限に引き出すことが可能な機能です。
放熱ややバッテリーの消費と引き換えに、デバイスのパワーを引き出す、富豪的プログラミングの醍醐味のような機能です。
パワー💪
実装コード例 とポイント
で、実装例です。
ポイント1: PBXProject.GetPBXProjectPath がおかしい
最初iOSでよくやるように実装したところ DirectoryNotFoundException
が出て正常に動作しませんでした。
DirectoryNotFoundException: Could not find a part of the path "/xxxx/Builds/visionOS/Unity-iPhone.xcodeproj/project.pbxproj".
よくよく見てみると
PBXProject.GetPBXProjectPath(path); は Unity-iPhone.xcodeproj
を返すのに、実際のプロジェクトは Unity-VisionOS.xcodeproj
となっていました。
そのため、無理くり置換する処理を入れています。この辺りはそのうちUnity側で改善するかもしれません。
projPath = projPath.Replace("Unity-iPhone.xcodeproj", "Unity-VisionOS.xcodeproj");
ポイント2: com.apple.developer.app-compute-category は array of strings
これは自分が悪いのですが、
key:com.apple.developer.app-compute-category のvalue は string ではなくarray of stringsでした。
この辺もちょっとハマりました。
という事で、以下のような実装で目的の動作ができました。
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System.IO;
public class AddCapabilityPostProcessor
{
[PostProcessBuild(0)]
public static void OnPostProcessBuild(BuildTarget buildTarget, string path)
{
if (buildTarget != BuildTarget.VisionOS)
return;
string projPath = PBXProject.GetPBXProjectPath(path);
//やむなくファイル名を置換する
projPath = projPath.Replace("Unity-iPhone.xcodeproj", "Unity-VisionOS.xcodeproj");
var proj = new PBXProject();
proj.ReadFromFile(projPath);
string targetGuid = proj.GetUnityMainTargetGuid();
// Entitlements ファイルのパスを取得/作成
string entitlementsFileName = "visionOS.entitlements";
string entitlementsPath = Path.Combine(path, entitlementsFileName);
// 既存の entitlements ファイルがなければ新規作成
PlistDocument entitlements = new PlistDocument();
if (File.Exists(entitlementsPath))
{
entitlements.ReadFromFile(entitlementsPath);
}
else
{
entitlements.Create();
}
// Capability を追加
PlistElementDict rootDict = entitlements.root;
rootDict.SetBoolean("com.apple.developer.kernel.increased-memory-limit", true);
//performance-headroom を追加したいので、app-compute-categoryを設定する
var arr = rootDict.CreateArray("com.apple.developer.app-compute-category");
arr.AddString("high");
// 保存
entitlements.WriteToFile(entitlementsPath);
// Xcode プロジェクトに entitlements ファイルを設定
proj.AddFile(entitlementsPath, entitlementsFileName);
proj.SetBuildProperty(targetGuid, "CODE_SIGN_ENTITLEMENTS", entitlementsFileName);
// 保存
proj.WriteToFile(projPath);
}
}
おしまい。
Discussion