大多数浏览器和
Developer App 均支持流媒体播放。
-
即插即用:向你的 Unity 游戏项目添加 Apple 框架
优化你的 Unity App 或游戏在 Apple 平台上的体验。学习如何利用以下六种插件将 Apple 技术直接运用到你的项目当中:Apple.Core、Game Center、游戏控制器、辅助功能、Core Haptics 和 PHASE。我们将介绍如何添加新的游戏机制,使你的游戏更易访问,以及如何利用最新的 Apple 功能和服务。
资源
- Accessibility
- Apple Unity Plug-Ins on GitHub
- Delivering Rich App Experiences with Haptics
- Game Controller
- Human Interface Guidelines: Game Center
- PHASE
相关视频
WWDC23
WWDC22
WWDC21
WWDC20
-
下载
♪ 柔和乐器演奏的嘻哈音乐 ♪ ♪ 大家好 我是 Jared Marsau 在 Apple 游戏技术部门工作 今天 我会和大家聊聊如何使用 一些精选 Apple 框架 为基于 Unity 开发的游戏 添加新特性 据我们所知 有许多开发者 在使用诸如 Unity 之类的工具 来构建游戏 我们的目标是为您带来最新的功能 无论您用的是哪一种工具 从今天开始 您可以使用一组新的 Unity 插件 来增强您的游戏 使用 Game Center 插件 来添加 GameKit 功能 比如: 玩家身份验证 排行榜 和游戏配对 使用 Game Controller 插件 来自定义输入和图标 进而获得支持 MFi 和第三方控制器的能力 使用 Accessibility 插件 来改善辅助功能使用 调动起 旁白 和 动态字体 等系统特性 如要集成 Apple 由数据驱动的 完善的触觉反馈系统 可以使用 Core Haptics 插件 如要添加先进的几何感知空间音频 可以使用 PHASE 插件 最后 使用 Apple.Core 插件 管理构建设置 简化构建流程 这一组插件初始套装能帮您 添加新游戏玩法机制 让您的游戏更加无障碍 还能助您更快地 利用上最新的功能和服务 我已经迫不及待地想要看看大家会用 这一组新的 Unity 插件 做出多么棒的游戏了 现在 让我们来详细了解一下这个项目 首先 我们会讨论这个项目的设计原则 然后 我会介绍项目概念和组织 接下来 我会讲一些 关于与项目库交互的关键点 最后 我会详细介绍一下各个插件 您可能已经知道 Apple 框架 是用模块化的方式封装各种功能的 这种方式能让您 为 App 挑选正确的技术 同时还保持代码的简洁和高效 在 Unity 插件中 我们遵循类似的模式 每个插件 都映射到一个单一的底层框架 这样您就可以根据游戏的需要 挑选所需的插件组合 每个插件都包含 Unity 所需的 C# 脚本 该脚本尽可能地直接映射 到底层框架 这种方法意味着 您面对底层框架的经验 可以直接继承到插件的使用上 在很多情况下 框架 API 以及基本概念 都可以无缝过渡 反过来说 通过学习这些插件 您也会在潜移默化中 学习底层框架 另一个重要的细节是 这些插件 都是作为 Apple 平台原生库开发的 这些库 像胶水一样连接着 C# 脚本 和底层框架 API Apple Unity 插件 是以 Unity 资源包的形式组织的 因此使用 Unity 编辑器的 内置 Package Manager 就可以管理它们与您的项目的集成 在某些情况下 插件还会包含 编辑器的扩展功能 让开发工作更加轻松 并且与您已经熟练掌握的 基于 Inspector 的 Unity 工作流程保持一致 当然 每个插件 还附带有详细的自述文件 示例 以及额外资源的链接 比如相关的 Apple Developer 文档 接下来 我会简要讲解一些关键工作流程概念 以帮助您入门 第一步是 克隆 GitHub 上的源代码 在那里您可以找到 所有的项目源代码和文档 这是每个人使用 Apple Unity 插件的第一步 克隆了代码库之后 您的首要任务之一就是构建插件 为了简化这个流程 代码库中包含了 一个 Python 脚本 存放在库根目录下:build.py 这个脚本会构建原生库 把它们复制到正确的位置 更新 Unity 元文件 打包插件 以及构建插件测试 这个插件是这样组织的: 用最简单的调用 构建所有插件 把它们打包成 tar 包 并保存到 Build 文件夹中 准备妥当 等待集成入您的 Unity 项目 请注意 完整构建和打包这些插件很重要 需要 Xcode Python3 npm 以及 Unity 最后 在项目库中 我们还有 关于使用 build.py 的详细文档 现在是时候让我们深入 这些插件的细节了 我会讲解如何把各个插件 加入到您的 Unity 项目中 简要介绍一下它们包含的功能 关键脚本概念 以及一些代码片段 或是 Unity 编辑器中的示例 主要着眼于 如何把它们集成入您的项目 让我们从最基础的插件开始 Apple.Core Apple.Core 把各个插件的构建设置统一到 Unity 项目设置窗口中 的单个偏好设置面板上 因为您编译了各个插件的原生库 Apple.Core 进而包含了一个资源处理器 它确保每个插件库在导入时 都会根据相应平台配置好 当构建您的项目时 Apple.Core 还包含了 用于后处理项目的脚本 以确保正确引用了这些原生库 尤其是在您的 Xcode 中间项目 由于每个插件都与一个底层框架互动 Apple.Core 还定义了 一些运行时交互操作类型 以简化 C# 脚本 和原生代码层之间的数据传递 最后 Apple.Core 是所有其他 Apple Unity 插件的依赖项 也就是它应该优先导入您的项目 一定要早于其它插件 在这个演示中 我会展示 如何把 Apple.Core 插件 导入一个新项目 并简单介绍一下 Apple 构建设置的偏好设置 一旦插件构建和打包完成 就可以用 Unity Package Manager 导入 Apple.Core 只需选择 “Add package from tarball…” 选项 并找到打包好的插件
编辑器就会 加载这个包并编译脚本 完成之后 Apple.Core 就可以用了
Apple.Core 主要的面向用户的功能 是在编辑器的项目设置窗口中 新增的 Apple 构建设置选项卡
导入一个 Apple Unity 插件之后 它所有的 可用构建选项都会出现在这里 无需额外设置 开箱即用 Apple.Core 有一些默认的配置选项 比如支持的最低 OS 版本 请注意 您还可以禁用 任何插件构建的后处理步骤
最后 您可以配置常用的安全设置 它会应用至 您的中间 Xcode 项目中 使用 Game Center 插件 来为您的游戏 带来更多趣味和互动 Game Center 是 Apple 的游戏社交网络 Game Center 能让玩家在 Apple 平台上 建立自己的身份 并启用很多功能 比如: 安全可靠的玩家身份验证 游戏内成就系统 共享的排行榜 玩家之间发送挑战 以及多人游戏匹配 您可以选择 把哪些 Game Center 功能 集成入您的游戏中 但一切都从玩家身份验证开始 把 Game Center 玩家身份验证加入您的游戏 Game Center 小组件 就可以在玩家的主屏幕 或是 App Store 中 展示您的游戏 而且 只需要很少的编程工作 就可以添加玩家身份验证 第一步是把 Apple.Core 和 GameKit 插件 添加到您的项目中 GameKit 插件 会连接到 Game Center 服务 进行身份验证时 它会连接到 Game Center 服务 并初始化 一个 GKLocalPlayer 对象 初始化完成之后 开始根据本地玩家资料 询问玩家限制情况 包括限制未成年玩家 访问成人或露骨内容 限制使用多人游戏功能 或禁用游戏内交流 管理 GKLocalPlayer 以及 它与 Game Center 服务 交互的一个简单方法是: 在 Unity 中定义一个组件 比如 这是一个简单的 Game Manager 组件定义 这个组件引用了 一个 GKLocalPlayer 它还在 Start 方法中 处理身份验证并询问玩家限制情况 玩家身份验证在游戏生命周期内 只需要发生一次 这就是这个 GameManager 组件的脚本 这是缓存 GKLocalPlayer 的字段 在组件的 Start 方法中 有对 GKLocalPlayer.Authenticate 的单次调用 这是一种返回 GKLocalPlayer 实例的静态方法 成功验证本地玩家的身份后 就该检查玩家的限制情况了 在代码中 检查玩家限制情况 体现为一系列的 Bool 检查 可以添加到 GameManager 组件脚本中的 try 代码块中 此处 True 意味着应该 限制本地玩家访问露骨内容 此处 True 意味着 应该限制本地玩家参与多人游戏 最后 此处 True 意味着 应该禁用游戏内交流 这就是在您的游戏中添加 玩家身份验证要更改的所有代码了 接下来 还需要两个额外步骤 以使您的游戏 充分利用 Game Center 的优势 首先 您需要把 Game Center 功能 添加到您的中间 Xcode 项目中 这使用 Xcode 项目 UI 即可完成 更多信息请查看 Apple Developer 文档文章 “Enabling and Configuring Game Center” 接下来 您需要使用 App Store Connect 把 Game Center 功能 加入到您的 App 中 更多信息请查看 App Store Connect 网页 完成这些步骤后 您就可以进行玩家身份验证 并确保一个安全的游戏环境了 玩家身份验证只是 Game Center Unity 插件 所提供的功能的 很小一部分 要学习如何提高您的游戏的曝光量 请查看 “Reach new players with Game Center dashboard”讲座 要学习更多 关于多人游戏和匹配的内容 请观看去年 “What’s new in Game Center” 讲座 控制器(主要是游戏手柄) 是玩家与 您创造的游戏世界 交互的主要途径 Game Controller 插件 可以轻松为您的游戏 带来灵活可靠的游戏控制器支持 Game Controller 插件 有相当多的功能 比如支持游戏控制器自定义 这个功能让玩家可以在一个地方 为所有游戏重新映射按键 按键图标功能 能保证连贯一致的用户体验 还有对所有 MFi 控制器 以及第三方控制器的支持 比如一部分索尼和微软的控制器 只需和其它插件一样 使用 Package Manager 把 Apple.Core 和 Game Controller 插件 添加到您的项目中 载入 Game Controller 插件后 第一步就是初始化 GCControllerService 我们接下来就会看到 这个服务 如何访问 控制器和它们的连接事件 初始化完成后 向 GCControllerService 询问 连接到系统的所有控制器情况 已连接的控制器会作为 GCController 对象 表示在 Game Controller 插件中 向每个已连接的 GCController 轮询控制器更新状态 轮询频率或高或低 主要根据您的游戏的需要 但 Unity 的定期更新循环 是一个比较好的起始点 一旦控制器状态更新之后 会开始测试各控制器上的 单独输入元素 比如按键 摇杆 等等 别忘了 在您的游戏生命周期内 玩家可能会添加或移除控制器 您可以注册回调函数 来管理控制器连接与断开事件 有个简单的方法可以用于 集成 Game Controller 插件 就是创建一个简单的输入管理组件 该组件有三个关键元素: 一个容器 其中包含了所有当前连接的控制器 一个 Start 方法 用于初始化 还有一个 Update 方法 用于处理 对输入信号的轮询和测试 首先 让我们来看看 Start 方法 这里可以很方便的布置所有必要的 一次性设置任务 游戏控制器服务的初始化 就应该在这里进行 还有已连接控制器的初始检查 以及为连接和断开事件 注册的回调函数 这是输入管理组件的脚本 所以的一次性设置代码 都在组件的 Start 方法里 包括调用了一次 GCControllerService.Initialize() 调用 GetConnectedControllers 会得到一个可枚举的容器 其中包含了所有当前连接的控制器 初始化的最后一步是注册回调函数 用于处理控制器连接和断开事件 初始化完成之后 输入管理器还需要一个 Update 方法 主要是为了轮询各已连接的控制器 以更新输入状态 并处理各控制器输入信号的状态 要轮询输入信号 首先 对已连接的控制器进行迭代 调用 GCController 的轮询方法 来收集最新状态 然后检查各个按键状态 并给出相应的响应 我简单介绍了一下如何使用 Game Controller 插件 来访问连接的控制器 并获取输入信号 要获取更多关于 Game Controller 框架的细节 了解第三方控制器 和非标准输入方式等主题 请查看往年的讲座: “Supporting New Game Controllers” 以及“Advancements in Game Controllers” 辅助功能是让技术触手可及 进而造福所有人 Accessibility 插件可以将 Apple 丰富的辅助技术 集成到您的 Unity 游戏中 Accessibility 插件可以让您 添加许多关键功能 比如 旁白(VoiceOver) 这个功能可以把以编程方式 标记的内容读给您的用户听 切换控制功能(Switch Control) 允许用户使用多种辅助输入设备 动态字体(Dynamic Type) 可以随用户所需 轻松缩放游戏内文本和 UI 以及 UI 适应性设置选项(UI Accommodation) 用来同步系统层级的 辅助功能偏好设置 关于 Accessibility 插件还有许多内容可以深入探讨 您可以查看讲座 “Add accessibility to your Unity games” 获得更多关于 Accessibility Unity 插件的知识 这个讲座中不仅有示例和应用实例 还能帮助您理解 Apple 平台上的辅助功能 可以做到些什么 有机会的话请务必看看那个讲座 在您的游戏中添加触觉反馈 能够大幅增强沉浸感 提高游戏体验 Core Haptics 插件 可以将 Apple 的 先进的触觉功能集成入您的游戏中 Core Haptics 插件 可以用一组触觉和声音事件 构建自定义的触觉模式 播放同步好的自定义声音和触觉 通过编程实时调整参数 定义或更新触觉反馈 Apple Haptic and Audio Pattern 文件格式 简称 AHAP 能以资源文件的形式 设计和存储您的触觉模式 使用 Unity 编辑器的 Inspector 窗口 调整您的 Core Haptics 模式 为了充分利用 Core Haptics 插件 您需要了解 Core Haptics 四个基本元素 以及它们之间的相互关系 其中 最高层级的元素是 CHHapticEngine 触觉引擎(Haptic Engine)代表了 通往设备上触觉模块的链接 要播放任何一种触觉模式 它都是不可或缺的 CHHapticEngine 创建了 CHHapticPatternPlayers 模式播放器(Pattern Player)用于控制 CHHapticPatterns 的播放 实现诸如播放 停止 暂停和恢复之类的功能 一个 CHHapticPattern 就是一个或多个 触觉与声音事件组成的逻辑组 CHHapticEngine 用这些模式来创建播放器 CHHapticEvents 是定义 一种触觉体验的构建单元 Core Haptics 则是数据驱动的 API 有了它 才能实现 以编程方式 直接写入脚本的方法 或是修改 AHAP 文件的方法 定义触觉模式 有一个简单的方法 在您的项目中添加 Core Haptics 就是创建一个 Haptics 组件 用来管理各个必要的 Core Haptics 对象 这是一个 Haptics 组件示例 其中包含了一个 CHHapticEngine 一个 CHHapticPatternPlayer 和一个 AHAP 资源文件 AHAP 资源文件是 由 Core Haptics 插件定义的 一种自定义 Unity 资源 它可以让您轻松地 导入导出 AHAP 文件 还可以作为一个 自定义的编辑器拓展 来管理模式的创建和自定义 让我们详细了解一下 首先 我会确保我的项目已经安装好了 Apple.Core 和 Core Haptics 插件 添加好之后 我就可以开始 使用触觉来改善游戏体验了 这是我基于之前的框图 创建的一个触觉组件 我们稍后再来看它的实现方法 现在 先把它附到我的飞机上
附加上去之后 会看到这个组件 需要一个 AHAP 资源文件 但我的 AHAP 资源文件夹是空的 让我新建一个 点击 Assets > Create > Apple > CoreHaptics > AHAP 创建好之后 让我给它 起一个酷炫而有创意的名字: MyHapticPattern Core Haptics 插件 自带 编辑器拓展 让我可以直接在 Inspector 窗口中调整触觉模式 在这里 我可以定义 CHHapticEvents 它构成了 CHHapticPattern 用于播放的部分 默认状况下 这是一个瞬态事件 但我也可以 很轻松地添加一个连续事件 UI 中有导入(Import) 导出(Export) 和重置(Reset)按键 重置会清空所有 我添加的事件 把触觉模式恢复到默认状态 导入和导出也是很棒的功能 它们让您可以 载入和保存项目 AHAP 文件 在这里 我导入了一个准备好的 AHAP 文件 名叫 Rumble 它会触发一个很棒的触觉效果 但我觉得需要做一点修改 现在我更新了触觉模式 我可以把它导出到 一个新的 AHAP 文件 好让我把这个改善过的触觉模式 共享给团队同事
现在我已经创建并调整了资源文件 让我回到飞机这里 把它指向 MyHapticPattern 好极了!一切就绪 定义并连接好触觉模式之后 剩下的就是要给 Haptics 组件 添加一些逻辑 好让它播放触觉模式 这可以分为两个方法: PrepareHaptics 和 Play 在 PrepareHaptics 中 触觉引擎会初始化 触觉模式播放器会被创建出来 Play 则会调用 CHHapticPatternPlayer 的 Start 方法来开始播放 这就是 Haptics 组件的脚本 字段被分别定义为触觉引擎 和触觉播放器 请注意 在字段中 添加一个 serializeField 属性 才可以在 editor UI 中 设置这个 AHAP 资源 接下来 添加创建 CHHapticEngine 的代码 启动它 然后通过 直接从引用资源中访问 AHAP 创建一个触觉模式播放器 当然 为播放器调用 Start 就会播放这个触觉模式 Core Haptics Unity 插件提供的工具 可以助您把游戏的沉浸感 上升到一个新的高度 请使用 Core Haptics 插件 去创造那些亦真亦幻的游戏时刻吧 要更深入了解 Core Haptics 请查看 “Introducing Core Haptics”讲座 要了解优秀的触觉体验的设计细节 请务必观看“Designing Audio-Haptic Experiences” 以及“Practice audio haptic design” 沉浸式的音频对优秀的游戏体验 无比重要 PHASE Unity 插件 可以助您释放创造潜力 在您的游戏世界中构建丰富的声景 PHASE 让您可以为游戏 提供复杂的动态声音体验 几何感知音频意味着声音是 从场景中发出的 并与其中的网格交互 有了回响和反射 您的游戏中的环境 听起来会更加逼真 您可以构建分层音频图 来实现游戏中的动态音频控制 PHASE 插件包括了 一组预定义的组件 可以直接使用 只需把它们附加到您的游戏对象上 就可以开始使用 PHASE 了 甚至连一行代码都不用写 第一个组件是 PHASEListener 它充当您的游戏场景中的“耳朵” 它根据位置 方向和回响预设值 处理音频 接下来是 PHASEOccluder 组件 PHASEOccluder 附加在游戏对象上 它附带几何数据 会在对象阻挡场景中的音源时 降低音量 接下来是 PHASESource 组件 它们附加在游戏对象上 会根据对象的 Transform 在您的游戏世界中定位声音 除了这些内置组件之外 PHASE 插件还定义了 一个自定义资源 即 SoundEvent 资源文件 声音事件描述了声音播放事件 还定义了场景中音源播放的声音 要启用 PHASE 插件 首先要确保项目中已经安装了 Apple.Core 和 PHASE 插件 安装好之后 我就可以把自带的组件 添加到场景中了 在这个示例项目中 有三个相关的游戏对象 飞机 建筑物和摄像机 首先 我会把 PHASEListener 组件 附加到摄像机上 如此一来 我就添加了这个场景中的“耳朵” 接下来 我会把建筑物设置为遮挡物 给它附加 PHASEOccluder 组件
最后 我要给这个场景添加一个音源 把 PHASESource 添加到飞机上 现在 这个音源要播放一些声音 所以我要给它附加一个声音事件 但 Sound Events文件夹是空的 让我们创建一个 点击 Assets > Create > Apple > PHASE > SoundEvent 创建好一个声音事件之后 PHASE 插件会立即打开 PHASE 声音事件编辑器窗口 这就是您构建声音事件的画布 我首先右键点击窗口的任意位置 弹出菜单允许我 为这个事件添加一个节点 因为我想播放一个音频片段(Clip) 或者创建一个采样器(Sampler)节点 我已经为这个项目 添加好了一架待机状态飞机的 音频素材 所以在这里我直接引用 我启用了循环播放 这样这架飞机就会一直发出嗡嗡声 要听到这架飞机的声音 我要把它路由至混音器(Mixer) 要创建混音器 我只需把输出线 拖拽到事件编辑器画布上 它就会显示创建混音器的选项
这样我的声音事件 就创建完成 准备就绪了 点击声音事件 我可以直接在 Inspector 中查看其设置 这样我调整数值时 就不必回到 声音事件编辑器中了 声音事件创建好后 就可以在之前附加到飞机上的 PHASESource 组件中引用它了 如此一来 就路由并配置好了 场景中的声音 可以播放了 PHASE Unity 插件 为游戏内声音设计 带来了全新的可能性 要更深入学习 PHASE 了解我今天介绍的这些概念 请务必查看 Apple Developer 文档网站 以及去年的 WWDC 讲座视频 我们对新 Apple Unity 插件的 概述就到这里 我今天讲了很多内容 如果您想要 了解更多关于 Apple Unity 插件的知识 我们在 GitHub 上的仓库 是一个绝佳的起点 那里有源代码 详细文档 以及各个插件的示例 要了解更多 关于在 Unity 游戏中 集成辅助功能的内容 请查看“Add accessiblity to your Unity games”讲座 也别忘了查看 “Reach new players with Game Center dashboard”讲座 来学习如何增加您的游戏的曝光量 感谢收看 ♪
-
-
9:02 - Game Center - Example game manager component - C#
using Apple.GameKit; public class GameManager : MonoBehaviour { private GKLocalPlayer _localPlayer; private async Task Start() { try { _localPlayer = await GKLocalPlayer.Authenticate(); } catch (Exception exception) { // Handle exception... } } }
-
9:23 - Game Center - Example game manager component continued - C#
try { _localPlayer = await GKLocalPlayer.Authenticate(); if (_localPlayer.IsUnderage) { // Hide explicit game content. } if (_localPlayer.IsMultiplayerGamingRestricted) { // Disable multiplayer game features. } if (_localPlayer.IsPersonalizedCommunicationRestricted) { // Disable in-game communication UI. } }
-
13:11 - Game Controller - Example input manager component - C#
using Apple.GameController; public class InputManager : MonoBehaviour { void Start() { // Initialize the Game Controller service GCControllerService.Initialize(); // Check for connected controllers var controllers = GCControllerService.GetConnectedControllers(); foreach (GCController controller in controllers) { // Handle controllers } // Set up callbacks to handle connected/disconnected controllers GCControllerService.ControllerConnected += _onControllerConnected; GCControllerService.ControllerDisconnected += _onControllerDisconnected; } }
-
13:50 - Game Controller - polling and input handling - C#
foreach (GCController controller in _myConnectedControllers) { controller.Poll(); // Check the 'South' button ('A' button on most controllers) if (controller.GetButton(GCControllerInputName.ButtonSouth)) { //Handle button pressed } // Check other controller inputs… }
-
20:30 - Core Haptics - Example haptics component - C#
using Apple.CoreHaptics; public class Haptics : MonoBehaviour { private CHHapticEngine _hapticEngine; private CHHapticPatternPlayer _hapticPlayer; [SerializeField] private AHAPAsset _hapticAsset; private void PrepareHaptics() { _hapticEngine = new CHHapticEngine(); _hapticEngine.Start(); _hapticPlayer = _hapticEngine.MakePlayer(_hapticAsset.GetPattern()); } private void Play() { _hapticPlayer.Start(); } }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。