大多数浏览器和
Developer App 均支持流媒体播放。
-
探索适用于 iOS、macOS 和 visionOS 的 RealityKit API
了解 RealityKit 中新的跨平台 API 如何帮你构建适用于 iOS、macOS 和 visionOS 的沉浸式 App。探索全新的悬停效果、光影效果以及门户切换功能,并在真实示例中查看实际应用效果。
章节
- 0:00 - Introduction
- 2:44 - Hover effects and input
- 9:05 - Force effects and joints
- 17:42 - Dynamic lights
- 20:17 - Portal enhancements
- 25:29 - Cross-platform capabilities
资源
相关视频
WWDC24
WWDC23
WWDC21
-
下载
大家好 我叫 Yidi 是 RealityKit 团队的工程师 在今天的讲座中 我会介绍一些全新的 RealityKit API 帮助你开发出色的空间计算 App
RealityKit 这个框架可为你的 App 提供高性能 3D 模拟和渲染功能 而且适用于多个操作系统 包括 iOS、iPadOS、macOS 和 visionOS 它提供了丰富的功能 可让 3D 内容 与现实世界环境无缝融合 从而让你能够创作出沉浸式 空间计算 App 和游戏 自 Apple Vision Pro 推出以来 我们收到了大家的 热烈反馈 我衷心感谢大家 提出的所有宝贵建议 和功能请求 而今天 我很高兴能与你分享 我们根据其中的许多反馈 对 RealityKit 做出了改进 推出了全新的功能 在本次讲座中 我们会使用其中 一些功能来构建“Spaceship”游戏 讲座下方列出了示例项目的链接 你可以把它下载下来跟着一起操作 我们的游戏希望重现孩子们 玩最喜欢的太空飞船玩具的感觉 游戏始于一个机库 这是一个安全的地方 玩家可以近距离 检查自己的太空飞船 然后 玩家将学习 如何使用双手作为输入 在物理环境中 驾驶飞船 熟悉飞行控制后 玩家就可以 飞往外太空 穿越小行星带 并运送宝贵的太空货物 他们甚至可以通过传送门 飞往遥远的星球 在构建这款游戏的过程中 我会介绍 一系列新的 RealityKit API 首先 我们会了解 如何使用悬停效果 与 3D 模型进行交互 然后使用手势追踪来 构建核心输入机制 接下来 我会通过力效应和关节 为游戏添加物理模拟 然后 我会添加动态灯光 来照亮场景 并使用阴影来 帮助玩家感知距离 之后 我会使用传送门 API 打开一扇通往 遥远外太空的传送门 并利用新的传送门增强功能 让我们的太空飞船飞向那里
最后 我会介绍 RealityKit 的跨平台功能 还会讲解如何轻松将我们的游戏 移植到其他 Apple 平台 内容丰富精彩 我们会踏上一场激动人心的奇妙之旅 现在就开始吧!
先来谈谈悬停效果和输入 在 visionOS 上 你可以在窗口、 空间容器或空间中显示 App 的内容 游戏开始时会以空间容器样式 显示机库中的太空飞船
玩家可以通过简单的拖动手势 旋转飞船 进行近距离观察 系统还为空间容器 提供了一个底板 用来根据玩家视线 显示相应的视觉反馈 不过 你可能会注意到 与底板不同 太空飞船并不会在玩家注视时 显示任何视觉高亮效果 让我们向太空飞船添加 一个 HoverEffectComponent 这样当玩家注视飞船时 它就会显示微妙的聚焦效果 这样可以让互动感觉 更加灵敏 但如果我们希望自定与游戏艺术风格 相匹配的效果 该怎么做? 我有一些好消息要告诉你! 今年 RealityKit 推出了 许多全新的 API 支持自定悬停效果 除了我们刚刚看到的 默认聚焦效果 还有两种全新样式可供使用: 高亮和着色器 新的高亮样式可以将均匀的 高亮效果应用于整个网格 当你使用 聚焦或高亮样式时 还可以自定样式的 着色色调和强度 而全新的着色器样式 与 Shader Graph 材质深度整合 可为你解锁 更多可能性 让我们尝试添加一个 带有色调的高亮效果 使它与飞船的外观相匹配 我还会调整强度 让这个效果 既清晰可见 又不显得突兀 为此 我将创建 一个 HighlightHoverEffectStyle 并将颜色设置为艺术家定义的黄色 将强度设置为 0.8 然后 我会使用这个样式 创建 HoverEffectComponent 并将它添加到飞船实体中 为实体添加新的高亮悬停效果 就是这么简单
聚焦和高亮 这两个全新自定选项 让你能简单快捷地 为 3D 内容添加悬停效果 而新的着色器样式 则更加强大且灵活 让你能在 Reality Composer Pro 中 使用 Shader Graph 材质 来制作高级视觉效果 借助这个功能 我添加了一种自定悬停效果 当你看向飞船的窗户时 它就会亮起 这看起来很棒 而且与飞船模型非常契合 为了实现这种效果 我使用了 Shader Graph 中新的 HoverState 节点 HoverState 节点提供了多项输入 其中包括一个强度值 当玩家看向飞船时 强度值会 从 0 变为 1 在 Reality Composer Pro 中 飞船的窗户已经设好了 Shader Graph 材质 我将 HoverState 节点添加到 这个材质中 并向 Mix 节点提供了 强度值 这样我们就可以在玩家看向飞船时 淡入飞船的发光颜色 最后 我们可以将 Mix 节点的输出 连接到 PBRSurface 的发光色
在代码中 我们只需 将悬停样式更新为着色器 并使用默认输入 使用 HoverState 节点 可以实现多种效果 例如 我的同事 Adrian 构建了 一款空间绘图 App 他使用一种着色器风格的悬停效果 为沿着 3D 画笔描边的 紫色光晕添加了动画效果 有关这一示例的更多详细信息 请观看今年 WWDC 的 “使用 RealityKit 构建空间绘画 App” 讲座 HoverEffectComponent 提供了强大的方法 让你能在用户注视 3D 实体时 提供丰富的视觉反馈 同时仍能保护用户的隐私 今年 SwiftUI 还推出了 自定悬停效果 API 欢迎观看讲座“在 visionOS 中 打造自定悬停效果”进一步了解
接下来 我们来定义 游戏的输入机制
当玩家准备好驾驶飞船 四处飞行时 他们会退出空间容器 进入一个混合的沉浸式空间
在这里 玩家双手操作 控制飞船 左手控制 飞船的飞行速度 当拇指和食指 指尖靠近时 飞船会飞得更快 右手控制 飞船的方向 当右手向上倾斜时 太空飞船也会向上倾斜 右手向左转时 飞船也向左转
要实现这种输入机制 我们需要 在 3D 空间中追踪玩家手势 在 visionOS 1 中 可以通过 ARKit 向 App 添加自定手势 追踪功能 今年 RealityKit 推出了 新的 Spatial Tracking API 让这项任务变得更加简单
SpatialTrackingSession 可以帮助 我们征得玩家对允许手势追踪的同意 设置完毕后 我们就可以 使用 RealityKit 锚点实体 来追踪玩家的手势 对于左手 我们创建两个锚点实体 一个用于食指尖 一个用于拇指指尖
在自定系统的 update 函数中 我们使用 Entity.position API 查询锚点实体的位置 我们还可以计算 两个锚点实体之间的距离 然后通过自定函数 将距离映射为油门值 距离越短 油门越大 最后 我们可以使用 这个油门值来对飞船进行加速 计算飞船前进方向的 一个力矢量 并将这个力添加到飞船实体上 右手控制的实现方式 与我们刚才看到的 代码类似 请查看本讲座链接的示例代码 了解详细的实现方式
现在 有了左手 和右手自定手势 玩家可以使用手作为输入 来驾驶飞船了
不错! 要进一步了解 SpatialTrackingSession API 还可以观看 Adrian 的讲座“使用 RealityKit 构建空间绘画 App” 玩家已经有了 可以驾驶的飞船 接下来让我们为飞行体验 增添一些乐趣 在这个过程中 我们将学习如何使用 新的力效应和物理关节 API 为了帮助玩家 练习驾驶技能 我在空间中添加了 行星和小行星 但绕着这些静态物体航行 感觉不够有挑战性 让小行星围绕 行星运行如何? 这模拟了现实世界中 天体的物理运作方式 力效应 API 是引入这类模拟的绝佳方式 力效应定义了一个空间容器 并持续对这个空间容器中的 物理物体施加力 对于行星 我们需要一种 将小行星拉向中心的 力效应
RealityKit 提供了四种 内置的力效应类型 让我们看看有没有哪一类 能满足我们的需求 恒定的径向效应 会对所有物理物体 施加恒定的向心力 涡旋效应会 对物理物体施加 围绕轴线循环的力 阻力效应会通过施加 与物理物体速度 成正比的力来 减慢物理物体的速度 湍流效应则会 对物理物体施加随机的力 恒定径向效应 非常接近我们想要的效果 但我们不希望行星 对所有小行星施加 完全相同的力 我们希望力的大小 根据它们与行星的距离而变化 我们可以通过在 RealityKit 中 定义一个自定力效应来实现这一点
在这里 我定义了 一个名为 Gravity 的类 它将包含自定力效应的逻辑 所有自定力效应 都符合 ForceEffectProtocol 其中包含以下三项要求 parameterTypes、forceMode 以及一个 update 函数
parameterTypes 可以帮助我们 告知物理引擎 计算这种力效应 需要哪些参数 对于重力效应 我们需要位置和距离 forceMode 控制物理引擎 如何解读来自力效应的 力矢量 对于“gravity” 我们只需将它设置为“force”
最后 我们将在 update 函数中 计算实际的力矢量 参数结构提供了 计算这些力所需的信息
我将首先从中 解包距离和位置 然后 我将遍历所有 受这个力效应影响的 物理物体 在本例中 这些物体 是指行星周围的小行星 我将定义一个自定函数 利用给定的 距离和位置值 计算力矢量 并通过在参数结构上 设置力来输出结果 物理引擎会接受这个力 并将力应用到物理物体上 好了 现在我们有了 自定力效应 接下来 让我们在场景中将它激活
首先 创建一个具有 Gravity 实例的 ForceEffect 对象 在这里 我还设置了 spatialFalloff 使它仅影响距离行星 8 米半径范围内的物理物体 并设置了 mask 使它仅影响小行星
最后 我将使用 ForceEffectComponent 向行星实体添加重力效应
让我们来看看实际的重力效应
嗯 重力效应 确实起作用了 但它将小行星 直接拉向中心 而不是驱动轨道运动 要解决这个问题 我们需要 为小行星指定一个沿轨道轨迹的 初始速度 来自行星的引力 将小行星拉向它 随着速度 抵消引力 我们便实现了轨道运动
让我们计算一下 小行星诞生时的轨道速度 利用小行星到行星的 半径和角度 我可以计算初始速度 然后 我将通过 PhysicsMotionComponent 为小行星设置初始速度 现在让我们来看看效果如何
不错!小行星终于 绕着行星运行了 借助力效应 API 的强大功能 我们只需一个自定力效应 就能实现这种轨道运动 现在我们已经有了一个 足够具有挑战性的小行星障碍赛道 接下来让我们 在飞船后面添加一个拖车 这样玩家就可以在飞越赛道的同时 运输太空货物了
要给飞船添加拖车 最简单的方法是 将拖车实体作为 飞船的子实体 然而 使用这种方法时 飞船和拖车之间的连接 看起来非常僵硬 我们可以使用物理关节 营造出更有趣味的效果 关节通过约束 将两个物理物体连接在一起
让我们制作一个允许旋转 但限制平移的关节 这就模拟了现实世界中 拖车的工作原理 使用这种关节 拖动拖车的感觉 更加真实有趣
要制作一个关节 我们需要在实体上添加一个销点 销点定义了相对于实体的 位置和方向 一个关节正好连接两个销点 飞船的销点在后面 拖车的销点在前面
我们需要一个关节 它可以 将两个销点之间的平移限制为零 但仍为沿三个轴的 旋转留出空间
与力效应一样 RealityKit 提供了多个内置关节 在没有任何约束的情况下 关节中的第二个实体 可以沿三个轴中的任意轴 自由平移或旋转 内置关节对第二个 实体如何平移或旋转 施加了约束 我们来看一看
固定关节不允许 平移和旋转 球面关节 不允许平移 但允许绕 Y 轴和 Z 轴 有限制地旋转 以及绕 X 轴自由旋转
旋转关节与球面关节类似 但限制更多 它只允许 绕 X 轴旋转 棱柱关节 也称为滑动关节 它只允许 沿 X 轴平移 最后 距离关节允许 在所有三个轴上自由移动 但前提是两个物体之间的距离 在给定范围内
对于我们的飞船和拖车 球面关节非常接近我们想要的效果 唯一不同的是 它完全不限制 沿 X 轴的旋转 但这没关系我们可以使用 自定关节类型来满足我们的需求
让我们来看看该如何实现 我通过 Reality Composer Pro 向飞船添加了一个 Hook 实体 它定义了销点的位置 因此不需要对转换进行硬编码 我将在代码中找到 hookEntity 并获取它相对于 飞船的位置
然后 我将使用 pins.set API 在飞船实体上 创建一个 hookPin 并使用 hookOffset 作为销点的位置 对拖车的销点执行同样的操作
接下来 让我们创建一个 连接两个销点的自定关节
自定关节 允许我们分别约束 围绕三个轴的角运动 我将角运动限制在 一个较小的范围内 并且额外限制绕 X 轴的 角运动 这样拖车就不会 上下旋转太多
与角运动类似 我们也可以 分别控制沿三个轴的线性运动 由于我们不需要任何平移 我将沿三个轴的线性运动 设置为固定不变
最后 为了激活关节 我将它添加到物理模拟中
使用我们的自定物理关节 拖车现在会遵循物理定律 跟随飞船的拖动飞行 看起来很不错 接下来 让我们来给飞船添加前照灯 提升玩家的驾驶体验 前照灯 不仅能照亮附近的物体 还能投射出阴影 这样玩家就能轻松辨别 距离障碍物有多远 为此 我们可以使用 今年引入 visionOS 的 动态灯光和阴影 RealityKit 提供了三种类型的灯光 聚光灯可照亮 锥形空间容器内的物体 它支持自定角度、 距离和衰减值 定向光可照亮 场景中的所有物体 点光源应用于特定物体
你可以自定灯光的 衰减半径和衰减指数
这三种光线都 支持自定颜色和强度 但只有聚光灯和定向光 可以投射阴影 在引入灯光和阴影时 建议你 时常检查 App 的性能 因为这些效果渲染起来 可能会比较耗费资源
现在让我们在飞船的前部 安装一个聚光灯 强光前灯可以 帮助玩家分辨 哪些物体靠近飞船 你可以通过两种方式 添加灯光和阴影 通过代码中的 Swift API 或使用 Reality Composer Pro 它提供了 调整光照行为的 UI 让我们来看看如何 在 Swift 代码中添加光影 与我在 Reality Composer Pro 中 为飞船的挂钩 设置实体类似 我添加了一个新的前照灯实体 来定义灯光的变换 在代码中 我将在飞船实体 层次结构中找到这个前照灯实体 并为它附加一个聚光灯
聚光灯的颜色 设置为黄色 我将强度设为 1 万流明 并将衰减半径设置为 6 这些值在我们的场景中效果很好
我们希望这个聚光灯能投射阴影 因此我还将为实体 创建并添加一个阴影组件
让我们来看看效果 有了前照灯和阴影 我们现在可以很容易地看到 飞船在飞近小行星时的危险情况
默认情况下 动态聚光灯和定向灯照亮的所有物体 都会投射阴影 如果不希望某些 物体投射阴影 可以给它们添加 DynamicLightShadowComponent 并将 castsShadow 设置为“false” 这段视频展示了 停用 castsShadow 后的小行星 我们的游戏已经 变得非常有趣了 我认为如果能添加一个传送门 将飞船传送到遥远的外太空 那将会非常酷 让我们使用传送门 API 来实现这个功能 它带来了许多 令人兴奋的全新增强功能 而这也同样离不开 你们宝贵的反馈 传送门通过网格表面 打开通往另一个世界的窗口 这个世界中的所有实体 都被传送门的几何图形所遮挡 注意 这颗行星 周围的小行星 仅在圆形传送门 表面内渲染
要进一步了解如何构建传送门 请观看标题为“使用 RealityKit 增强你的空间计算 App”的 WWDC23 讲座 在 visionOS 1 上 物体只能完全 位于传送门内部或外部 这次发布的 RealityKit 增加了传送门穿越增强功能 使物体可以顺利 穿越传送门表面 进入传送门 或者从传送门出来 在这段视频中 我们看到了 两艘飞船 左侧的飞船 停用了传送门穿越功能 因此当它飞出传送门时会被遮蔽 而右侧的飞船 启用了传送门穿越功能 因此它可以顺利 飞出传送门 启用传送门穿越功能 需要在两个位置进行设置 首先 要在创建传送门组件时 设置穿越模式 你可以将模式 设置为平面来启用穿越 或者设置为停用 来关闭穿越 如果选择使用平面 请确保它与传送门几何体本身重合 在我们的游戏中 与传送门重合的平面是正 Z 平面 除了穿越传送门之外 现在还可以为传送门 定义一个裁剪平面 同样将它设置为正 Z 平面
另一项设置是 围绕飞船实体进行的 默认情况下 传送门世界中的实体 并没有启用穿越传送门功能 为了启用飞船的穿越功能 我将添加一个穿越传送门组件 这样就可以了 我们的飞船现在可以 飞进传送门了
嗯...我注意到 飞船穿过传送门时 有一个奇怪的地方 飞船在穿越传送门平面时 照明会有明显的过渡 你可以在飞船的机翼上看到这一点
这种刺眼的光线截断 是由传送门内外不同的 光照环境造成的 对于启用了传送门穿越功能的模型 当它位于传送门内部时 自定 ImageBasedLightComponent 会负责照亮 以星域图像为例
当模型位于传送门之外时 它会从环境探针 接收额外的光照 这近似于 所处物理环境的光线
当物体刚穿过 传送门时 它同时存在于 传送门内和门外 门内部分由传送门的 ImageBasedLightComponent 星空照亮 门外部分则由 两个光源共同照亮: 星域和环境探针
要使光效过渡更加顺畅 我们可以使用 EnvironmentLightingConfigurationComponent 这个组件控制 实体从环境探针接收的 光照量 特别是对于 传送门外的部分 它提供了一个 environmentLightingWeight 值 值为 1 表示物体 从环境探针获得全部光照 值为 0 表示 物体没有从环境探针获得任何光照 当飞船位于传送门外时 可以将 environmentLightingWeight 设置为 1 这样它就能获得外部照明 当飞船接近传送门时 可以逐渐 将这个值从 1 降为 0 这样当飞船开始 穿越传送门时 就只能接收到 传送门世界内部的光照了 为了在代码中实现这一点 我将创建一个 EnvironmentLightingConfigurationComponent 我会追踪飞船与 传送门表面的距离 并使用自定函数 将距离值映射到 环境照明权重值 当距离变小时 也就是飞船接近传送门时 我会降低权重 飞船每次移动时 我都需要重新计算权重 并更新飞船实体的组件 让我们来看看这段代码的实际效果
不错! 现在 飞船在接近 传送门表面时 拥有流畅的光照过渡 EnvironmentLightingConfigurationComponent 是一种配置 App 光效的强大方式 即使你的 App 不使用传送门 它也非常有用
要深入了解新传送门 增强功能的工作原理 强烈建议查看 developer.apple.com 上的 PortalComponent 文档
太棒了! 到了这一步 我们构建的 “Spaceship”游戏已经功能完备 可在 visionOS 上正常运行 我们可以看到手势输入、 力效应、关节、灯光和阴影 以及传送门都在协同工作 让我们的飞船体验跨平台运行 岂不更棒? 随着这一版 RealityKit 的发布 你现在可以将 visionOS 中的 空间计算体验 无缝移植到 iOS、iPadOS 和 macOS 只需对代码进行极少的改动 就可以为其他 Apple 平台 构建体验 而且我们还添加了 针对 RealityKit 许多功能的支持 确保整个流程顺畅无间 这包括 RealityView、 ShaderGraph、粒子发射器、传送门、 悬停效果、文本等 这也是开发 跨平台工具和管道 以加速 App 开发的 绝佳机会 现在 让我们使用 其中一些跨平台功能 将“Spaceship”游戏 移植到 iPadOS 得益于 如此广泛的跨平台支持 “Spaceship”中的大部分代码 根本无需更改 我们为悬停特效、力效应、 关节、光影和传送门穿越 编写的所有代码 都可以保持不变 那么我们需要改变什么呢
首先 在 visionOS 上 我们可将 UI 布置在玩家周围的独立窗口中 在 iPadOS 上 我们可以 将 UI 直接放置在屏幕上 其次 在 visionOS 上 我们使用 ImmersiveSpace 作为空间体验的入口 在 iPadOS 上 我们可以 通过 RealityView 直接在屏幕上 显示空间体验
RealityView 在 iOS、iPadOS 和 macOS 上都推出了新的增强功能 包括相机模式控制、后期处理等 我们希望使用现实场景追踪功能 并将摄像头源作为背景 因此 我将 RealityView 的 摄像头模式设置为现实场景追踪
最后 在 visionOS 上 我们使用 基于手势追踪的输入来驾驶飞船 在 iPadOS 上 多点触控 手势作为一种输入范例 与这个平台的优势 相得益彰 因此 我将通过新的多点触控控制 视图过渡到基于多点触控的输入 左侧的滑块用于 控制油门 右侧的虚拟操纵杆 用于控制俯仰和滚动 将两只手的职责分开 与我们的 visionOS 输入方案 非常契合 完成这些更改后 “Spaceship”游戏 便可在 iPad 上流畅运行 所有 RealityKit 功能 仍可在这里使用 与在 visionOS 上的运行方式类似 我们可以进入机库视图 用同样的拖动手势 与飞船互动 还可以借助现实场景追踪 并将摄像头源作为背景 来在物理环境中驾驶飞船 由于各个平台都能享用 同样出色的 RealityKit 功能 你就可以非常轻松地让自己的 App 在 visionOS、iOS、iPadOS 和 macOS 上顺畅运行
太棒了! 现在 功能丰富的“Spaceship”游戏 就构建好了 它不仅兼容 visionOS 还能在 iPadOS 上运行 在“Spaceship”游戏开发中 我们重点专注了 模拟和渲染方面的效果 但它还没有任何音效 我的同事 James 将介绍 他如何为这款游戏制作空间音频 请观看讲座 “利用 RealityKit 音频 让空间计算 App 更加引人入胜” 在讲座中 他不仅会介绍 如何使用 RealityKit 的音频 API 还会分享创作空间音频的 最佳实践 此外还有许多 RealityKit 功能 由于时间有限 本场讲座无法一一为你介绍 下面是其中一些功能的简要介绍 LowLevelMesh 和 LowLevelTexture 为构建和更新网格及纹理资源 提供了低级别访问权限 动画系统 解锁了许多新功能 包括在 Reality Composer Pro 中 创建动画时间线 BillboardComponent 推出了一种隐私保护方式 使实体始终面向用户 PixelCast 可通过 基于渲染的方法 实现完美的像素实体选择 细分表面 让你无需创建密集网格 就能渲染光滑的表面 要进一步了解这些功能 请访问 developer.apple.com 哇!内容真的很多! 让我们回顾一下今天所学的内容 我们首先为飞船添加了 自定悬停效果 并使用新的空间追踪 API 构建了基于手势控制的机制 来驾驶飞船四处飞行 我们使用力效应和关节 为场景添加了物理效果 使它更加有趣好玩 然后 我们使用动态灯光和阴影 使体验看起来更加生动 我们还引入了传送门穿越功能 将飞船传送到外太空 最后 我们利用 RealityKit 的 跨平台 API 支持 使飞船游戏 可以在 iPad 上运行 别忘了观看“使用 RealityKit 构建空间绘画 App” 和“利用 RealityKit 音频让空间 计算 App 更加引人入胜”讲座 了解 RealityKit 今年推出的 许多其他新功能 我非常期待看到你 利用这些功能打造的 精彩体验 感谢观看!
-
-
4:24 - Add a highlight HoverEffectComponent
// Add a highlight HoverEffectComponent let highlightStyle = HoverEffectComponent.HighlightHoverEffectStyle(color: .lightYellow, strength: 0.8) let hoverEffect = HoverEffectComponent(.highlight(highlightStyle)) spaceship.components.set(hoverEffect)
-
5:55 - Add a shader effect
// Add a shader effect let hoverEffect = HoverEffectComponent(.shader(.default)) spaceship.components.set(hoverEffect)
-
8:04 - Control acceleration with left hand
// Control acceleration with left hand class HandTrackingSystem: System { func update(context: SceneUpdateContext) { let indexTipPosition = indexTipEntity.position(relativeTo: nil) let thumbTipPosition = thumbTipEntity.position(relativeTo: nil) let distance = distance(indexTipPosition, thumbTipPosition) let throttle = computeThrottle(with: distance) let force = spaceship.transform.forward * throttle spaceship.addForce(force, relativeTo: nil) } }
-
10:50 - Adding a gravity force effect
// Adding a gravity force effect struct Gravity: ForceEffectProtocol { var parameterTypes: PhysicsBodyParameterTypes { [.position, .distance] } var forceMode: ForceMode = .force func update(parameters: inout ForceEffectParameters) { guard let distances = parameters.distances, let positions = parameters.positions else { return } for i in 0..<parameters.physicsBodyCount { let force = computeForce(distances[i], positions[i]) parameters.setForce(force, index: i) } } }
-
12:14 - Activating the gravity force effect
// Activating the gravity force effect let gravity = ForceEffect(effect: Gravity(), spatialFalloff: SpatialForceFalloff(bounds: .sphere(radius: 8.0)), mask: .asteroids) planet.components.set(ForceEffectComponent(effects: [gravity]))
-
13:11 - Using PhysicsMotionComponent
// Calculate initial velocity of the asteroid using radius and angle let velocity = calculateVelocity(radius, angle) let physicsMotion = PhysicsMotionComponent(linearVelocity: velocity) asteroid.components.set(physicsMotion)
-
16:19 - // Add a custom joint
// Add a custom joint guard let hookEntity = spaceship.findEntity(named: "Hook") else { return } let hookOffset: SIMD3<Float> = hookEntity.position(relativeTo: spaceship) let hookPin = spaceship.pins.set(named: "Hook", position: hookOffset) let trailerPin = trailer.pins.set(named: "Trailer", position: .zero) var joint = PhysicsCustomJoint(pin0: hookPin, pin1: trailerPin) joint.angularMotionAroundX = .range(-.pi * 0.05 ... .pi * 0.05) joint.angularMotionAroundY = .range(-.pi * 0.2 ... .pi * 0.2) joint.angularMotionAroundZ = .range(-.pi * 0.2 ... .pi * 0.2) joint.linearMotionAlongX = .fixed joint.linearMotionAlongY = .fixed joint.linearMotionAlongZ = .fixed try joint.addToSimulation()
-
19:12 - // Add a spotlight with shadow
// Add a spotlight with shadow guard let lightEntity = spaceship.findEntity(named: "HeadLight") else { return } lightEntity.components.set(SpotLightComponent(color: .yellow, intensity: 10000.0, attenuationRadius: 6.0)) lightEntity.components.set(SpotLightComponent.Shadow())
-
20:01 - Disable shadow
// Disable shadow let component = DynamicLightShadowComponent( castsShadow: false) entity.components.set(component)
-
21:36 - Enable portal crossing
// Enable portal crossing portal.components.set(PortalComponent(target: portalWorld, clippingMode: .plane(.positiveZ), crossingMode: .plane(.positiveZ))) spaceship.components.set(PortalCrossingComponent())
-
24:33 - Configure environmental lighting on the spaceship
// Configure environmental lighting on the spaceship var lightingConfig = EnvironmentLightingConfigurationComponent() let distance: Float = computeShipDistanceFromPortal() lightingConfig.environmentLightingWeight = mapDistanceToWeight(distance) spaceship.components.set(lightingConfig)
-
27:21 - World tracking camera
// World tracking camera RealityView { content in #if os(iOS) content.camera = .worldTracking #endif }
-
27:59 - Multi-touch control views
// Multi-touch control views #if os(iOS) struct MultiTouchControlView : View { var body: some View { HStack { ThrottleControlView() Spacer() PitchRollControlView() } } #endif
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。