为 iOS 平台构建 Unity 项目时,Unity 将创建一个包含 Xcode 项目的文件夹。为了在将应用程序部署到设备上之前对此应用程序进行编译和签名,您需要该项目。此外,还需要使用该项目来准备和捆绑游戏,以便分发到 App Store 上。自 Unity 2019.3 起,Xcode 项目结构已更改,旨在支持通过 Unity 用作库将 Unity 集成到原生 iOS 应用程序中。
构建 iOS 项目之前,务必在 iOS Player Settings****(菜单:Edit > Project Settings > Player Settings)中设置 Bundle Identifier。还可以选择应用程序的目标是模拟器还是实际设备。为此,请更改 SDK version 字段。
每个生成的 Unity iOS Xcode 项目都具有以下结构和目标:
Classes 文件夹包含用于集成 Unity Runtime 和 Objective-C 的代码。Unity 将应用程序的入口点存储在此文件夹内的 main.mm 和 UnityAppController.mm/h 文件中。您可以自行创建派生自 UnityAppController 的 AppDelegate,或者如果您的任何插件包含 AppController.h_,则您可以改为包含 UnityAppController.h。如果 Plugins/iOS_ 文件夹包含 _AppController.mm/h_,可以对它们进行合并和重命名。
InternalProfiler.h 文件还定义一个条件编译器来启用内部性能分析器。此文件夹中的代码不会经常更改,您可以在此处放置自定义类。如果您选择 Append 模式,Xcode 会在不同构建中保留对此文件夹的更改。但是,此功能不支持多个构建目标,并且需要固定结构的 Libraries 文件夹。
Unity 的内部性能分析器具有快速且不易察觉的特点,并提供以下相关基本信息:
有关更多信息,请参阅内置性能分析器的相关文档。
此文件夹包含应用程序的序列化资源以及 .NET 程序集(.dll 或 .dat 文件),其形式为完整代码或元数据(取决于代码剥离设置)。machine.config 文件可以设置各种 .NET 服务(例如安全性和 WebRequest)。Xcode 在每次构建时都会刷新此文件夹的内容。您不应对其进行任何更改。
默认情况下,_Data_ 文件夹的 Target Membership 设置为 Unity-iPhone 目标,并且 Unity Runtime 会在 mainBundle
中搜索该文件夹。要更改 Unity Runtime 用于查找 Data 文件夹的默认捆绑包,请在 UnityFramework 实例上调用 setDataBundleId: "com.my.product"
,然后调用运行函数之一。例如,如果您希望拥有 Data 以及 UnityFramework 调用,请使用 setDataBundleId: "com.unity3d.framework"
并将 Target Membership 设置为 UnityFramework。
注意:仅当 Data 文件夹是应用程序目标的一部分而不是 UnityFramework 目标的一部分时,才支持按需加载资源 (On-Demand Resources)。
Libraries 文件夹包含用于 IL2CPP 的 libil2cpp.a。libiPhone-lib.a 文件是 Unity Runtime 静态库,_RegisterMonoModules.cpp_ 将 Unity 原生代码与 .NET 绑定。Xcode 在每次构建时都会刷新此文件夹的内容。您不应对其进行任何更改。
您可以将自定义文件放置于此。
图标和启动画面(.png 文件)位于 Unity-iPhone 文件夹中的资源目录中。Unity 自动管理这些文件。启动屏幕、它们的 XML 接口构建器(.xib 文件)和 Storyboard 文件存储在项目的根文件夹中。要在 Unity 中设置它们,请使用 Player Settings 窗口(菜单:Edit > Project Settings > Player Settings)。创建自定义启动图像时,请确保图像遵守 Apple 的人机接口指南。
可从 Unity 的 Player Settings(菜单:Edit > Project Settings > Player Settings,然后选择 Other 部分并向下滚动到 Identification 部分;有关更多详细信息,请参阅 iOS Player 设置 - Identification 的相关文档)中管理 Unity-iPhone 目标内的 /Info.plist 文件(通过 mainBundle
进行访问)。Unity 在构建播放器时会更新此文件,而不是进行替换。除非迫不得已,否则不要对其进行更改。
/UnityFramework/Info.plist 文件(通过 bundleWithIdentifier:@"com.unity3d.framework"
进行访问)是 UnityFramework 的一部分。您可以将一些值保留在此处,而不是 mainBundle 的 /Info.plist 文件中,这样能确保如果将 UnityFramework 移至另一个应用程序中,您仍然可以获取这些值。
这些文件包括 Xcode 项目文件(.xcodeproj 文件)以及仅在 Project Navigator 中显示的框架链接。
使用命令行参数来指定构建设置时,这些设置会影响所有 Xcode 项目目标。为了防止发生这种情况,某些构建设置具有后缀版本。您可以使用这些后缀版本来指定构建设置影响的目标。这是通过用户定义的设置来实现的(*APP 后缀用于应用程序目标,*FRAMEWORK 后缀用于框架目标)。
使用 xcodebuild 进行构建时,请将后缀版本用于:
PRODUCT_NAME -> PRODUCT_NAME_APP
PROVISIONING_PROFILE -> PROVISIONING_PROFILE_APP
PROVISIONING_PROFILE_SPECIFIER -> PROVISIONING_PROFILE_SPECIFIER_APP
OTHER_LDFLAGS -> OTHER_LDFLAGS_FRAMEWORK
根据您的自定义构建管线,您可以扩展此列表以涵盖其他设置。
要修改生成的 Xcode 项目,请使用 Xcode.PBXProject。
从 Unity 2019.3 开始,已弃用 PBXProject.GetUnityTargetName
和 pbxProject->TargetGuidByName("Unity-iPhone")
。接下来可以改用 pbxProject->GetUnityFrameworkTargetGuid()
或 pbxProject->GetUnityMainTargetGuid()
:
// 已弃用
string targetGuid = proj.TargetGuidByName("Unity-iPhone");
string targetGuid = proj.TargetGuidByName(PBXProject.GetUnityTargetName());
// 改为以下调用之一
string targetGuid = proj.GetUnityFrameworkTargetGuid();
string targetGuid = proj.GetUnityMainTargetGuid();
如果需要在包或自定义构建后处理器中同时支持新旧代码路径,请遵循以下步骤:
1.尽可能依靠插件导入器功能(例如,用于指定其他框架)。 2.使用反射:
string mainTargetGuid;
string unityFrameworkTargetGuid;
var unityMainTargetGuidMethod = proj.GetType().GetMethod("GetUnityMainTargetGuid");
var unityFrameworkTargetGuidMethod = proj.GetType().GetMethod("GetUnityFrameworkTargetGuid");
if (unityMainTargetGuidMethod != null && unityFrameworkTargetGuidMethod != null)
{
mainTargetGuid = (string)unityMainTargetGuidMethod.Invoke(proj, null);
unityFrameworkTargetGuid = (string)unityFrameworkTargetGuidMethod.Invoke(proj, null);
}
else
{
mainTargetGuid = proj.TargetGuidByName ("Unity-iPhone");
unityFrameworkTargetGuid = mainTargetGuid;
}