Unity 开发 VisionOS 游戏初探

🔔 里程碑

  • 2023年6月5日,苹果发布 Apple Vision Pro 与 visionOS。

  • 2023年6月6日,Unity visionOS Beta 项目正式启动。

  • 2023年11月17日,Unity visionOS Beta 测试正式开放。

  • 2024年1月8日,苹果宣布 Apple Vision Pro 1月19日开始预购,2月2日美国正式发售。

Beta 测试版本发布频繁,以下所述软件版本等内容具有时效性。

1 概述

​ 2023年6月5日,在 WWDC23 全球开发者大会上,苹果发布了其第一款 AR 眼镜 — Apple Vision Pro,其搭载了 “第一个为空间计算而设计的操作系统” — visionOS。作为苹果 visionOS 原生合作方之一,Unity 将 PolySpatial 技术与 visionOS 深度集成,提供了被开发者熟知且性能强大的创作工具,用于创建 Apple Vision Pro 沉浸式游戏和应用。

​ Unity 支持三类 VisionOS 应用程序的创建:

  • virtual reality (VR),完全沉浸式的虚拟现实应用程序。

  • mixed reality (MR):沉浸式混合现实应用程序。使用 Unity 新开发的 PolySpatial 技术。

    visionOs 中 MR 分为两种模式,“Shared” 和 “Exclusive”。在 “Shared” 模式下,应用程序是有边界的(Bounded Volumes),它可以与其他应用共存于混合现实空间内。在“Exclusive”模式下,应用程序是无界的(Unbounded Volumes),此时它拥有整个混合现实空间,其它应用程序将不可见。

  • windowed:窗口应用程序。

2 环境准备

2.1 设备及软件要求

​ 软件及设备要求:docs.unity3d.com/Packages/co…

com.unity.polyspatial.visionos 是 Unity 将 PolySpatial 技术与 visionOS 深度集成核心包,点击页面左上角可切换不同版本,查看不同软硬件要求。

Unity 开发 VisionOS 游戏初探

例如,com.unity.polyspatial.visionos 0.6.3 版本中,要求如下:

设备及软件 要求
Mac M1 / M2 芯片,暂不支持 Intel 芯片
XCode 版本 15.1 beta
visionOS 版本 随 XCode 安装即可
Unity 版本 2022.3.11f1 – ~
Unity Polyspatial 包版本 0.6.3

2.2 账号许可证

​ 目前 Unity visionOS Beta 测试向所有 Unity Pro、Unity Enterprise 和 Unity Industry 客户正式开放。如果是 Unity Personal 或 Unity Plus 用户,可以申请免费 30 天试用。

Unity Pro 试用版(免费30天)申请地址:unity.com/pages/pro-f…

⚠️ 如果打开试用申请链接后仍为付费定制,需要科学上网。

⚠️ 无相应许可证权限无法安装后续依赖包。

2.3 安装 Unity Hub

​ Unity Hub 下载地址:unity.com/download

⚠️ 需使用上述地址下载,国内版下载地址 unity.com/cn/download 下载 Unity Hub 客户端安装 Unity 时无 visionOS Build Support(experimental) 模块选项。

2.4 安装 Unity

​ 依据 1.1 中要求,下载 Unity 客户端,必须选择 iOS Build Support 与 visionOS Build Support(experimental) 模块。

Unity 开发 VisionOS 游戏初探

2.5 XCode 与 VisionOS 安装

VisionOS 安装过程中会频繁失败多次,点击重试即可。

Unity 开发 VisionOS 游戏初探

3 应用创建与导出

3.1 初始化

3.1.1 应用创建

​ 必须使用 Universal Render Pipeline (URP) 和 Built-in Render Pipeline 渲染管线,推荐 URP。所以在创建应用时,选择 “3D(URP)核心模板”。

Unity 开发 VisionOS 游戏初探

3.1.2 配置编译平台

​ 菜单栏 File -> Build Settings -> Platform 选择 “visionOS(experimental)” -> Switch Platform。

Unity 开发 VisionOS 游戏初探

​ 菜单 Edit -> Project Settings -> Player -> 选择 Apple Vision Pro 图标 -> Other Settings -> Target SDK -> Simulator SDK。由于当前仅能在 Apple Vision Pro 模拟器中模拟相关功能,故此处 SDK 选择 Simulator SDK。

Unity 开发 VisionOS 游戏初探

3.1.2 安装 Apple visionOS XR Plugin

​ 菜单栏 Window -> Package Manager -> Add package by name -> com.unity.xr.visionos。它将为应用程序提供 visionos 的 xr 功能。

安装 Apple visionOS XR Plugin 过程中,Unity 会弹出提示安装 Input System,这是使用 Unity 开发 visionOS 时的输入系统,运行并自动重启即可。

Unity 开发 VisionOS 游戏初探

3.1.3 配置 XR Plugin-in Management

​ 安装完成 Apple visionOS XR Plugin 后,需要配置使用此插件。

​ 菜单栏 Edit -> Project Settings -> XR Plugin-in Management,选择 Apple Vision Pro 图标 -> 勾选 Apple visionOS,以表明 XR 开发插件提供者。

Unity 开发 VisionOS 游戏初探

​ XR Plugin-in Management -> Apple visionOS,此时 App Mode 默认为 “Virtual – Full Immersive Space”,开发完全沉浸式的虚拟现实应用程序(VR)时,保持此默认即可。如果开发沉浸式混合现实应用程序(MR),需选择“Mixed Reality – Volume or Immersive Space”。

此时如果选择“Mixed Reality – Volume or Immersive Space”,会提示需要安装 PolySpatial 相关包。这也就是【1 概述】章节提到的使用 Unity 开发 visionOS 应用需要使用 Unity 全新的 PolySpatial 技术。相关包安装见 3.3.1 章节。

Unity 开发 VisionOS 游戏初探

​ Hands Tracking Usage Description 与 World Sensing Usage Description 简单输入即可。

Unity 开发 VisionOS 游戏初探

​ XR Plugin-in Management -> Project Validation -> fix all。

Unity 开发 VisionOS 游戏初探

3.2 VR 应用

3.2.1 准备

​ 先前使用 Unity 开发过一款趣味游戏“糖果大作战”,其使用了 URP 渲染管线。此次探索 visionOS VR 游戏选择对其精简及简单改造。

Unity 开发 VisionOS 游戏初探

3.2.2 核心代码

​ 除去游戏玩法核心代码外,对原“平面掌游”的改造主要涉及摄像机触发方式两部分。

​ 在 3.1.2 安装 Apple visionOS XR Plugin 时,可以看到其拥有 Samples,选择 Import “VR Sample – URP”,其已对相机及相关脚本引用有了基础配置。选择其作为改造游戏的相机并调整游戏布局以适配 VR 场景。

Unity 开发 VisionOS 游戏初探

​ “糖果大作战”中使用滑动屏幕蓄力,选择目标点,扔出糖果击伤对方。那么在 VR 场景中,如何进行蓄力与选择目标呢?与大多数头戴式 VR 设备一样,采用检测输入控点状态 与 Ray 射线结合形式。通过 Ray 选择目标,输入控点判断当时是否持续输入以进行蓄力。

各类设备的监听触发逻辑使用方式基本相同,只是相关 SDK 方法不同。例如:

  • 键盘:Keyboard.current.aKey.wasPressedThisFrame(A键按下) 与 Keyboard.current.aKey.wasReleasedThisFrame (A键抬起) 等。
  • 鼠标:Mouse.current.leftButton.wasPressedThisFrame(鼠标左键按下) 与 Mouse.current.leftButton.wasReleasedThisFrame(鼠标左键抬起)等。
  • 触屏: Touchscreen.current.press.wasPressedThisFrame (触屏按下) 与 Touchscreen.current.press.wasReleasedThisFrame(触屏抬起)等。
  • visionOS:VisionOSSpatialPointerPhase.Began(触点开始) 与 VisionOSSpatialPointerPhase.Ended(触点结束)等。

原代码:

using UnityEngine.InputSystem;

public class Demo : MonoBehaviour {
  	void Update()
  {
      if (Touchscreen.current.press.wasPressedThisFrame)
      {
        // 手指触摸屏幕开始的操作
      }
      else if (Touchscreen.current.press.isPressed)
      {
        // 手指长按屏幕瞄准操作
      }
      else if (Touchscreen.current.press.wasReleasedThisFrame)
      {
        // 手指离开屏幕的操作
      }
  }
}

适配 visionOS 代码:

using UnityEngine.XR.VisionOS;
using UnityEngine.XR.VisionOS.InputDevices;

public class Demo : MonoBehaviour {
  	// PointerInput 来自上文 VRSample - URP 中 PointInput.cs,由 com.unity.inputsystem:InputActionCodeGenerator 自动生成。
  	private PointerInput m_PointerInput;
 
    void OnEnable()
  {
    m_PointerInput ??= new PointerInput();
    m_PointerInput.Enable();
  }

  void OnDisable()
  {
    m_PointerInput.Disable();
  }

  void Update()
  {
    var primaryTouch = m_PointerInput.Default.PrimaryPointer.ReadValue<VisionOSSpatialPointerState>();
    var phase = primaryTouch.phase;

    if (phase == VisionOSSpatialPointerPhase.Began)
    {
      var rayOrigin = primaryTouch.startRayOrigin;
      var rayDirection = primaryTouch.startRayDirection;
      var ray = new Ray(rayOrigin, rayDirection);
      var hit = Physics.Raycast(ray, out var hitInfo, Mathf.Infinity);

      if (hit)
      {
         // 开始使用 hitInfo 获取目标位置级执行蓄力等操作
      }
    }
    
    if (phase == VisionOSSpatialPointerPhase.Ended)
    {
      // 结束蓄力,执行发动攻击等操作
    }
  }
}

​ 同时,由于游戏由 2D 屏幕变为了 VR 场景,所有按钮需添加 Collider 以供 Ray 碰撞检测触发。

using UnityEngine.XR.VisionOS;
using UnityEngine.XR.VisionOS.InputDevices;

public class Demo : MonoBehaviour {
  	private PointerInput m_PointerInput;
 
    void OnEnable()
  {
    m_PointerInput ??= new PointerInput();
    m_PointerInput.Enable();
  }

  void OnDisable()
  {
    m_PointerInput.Disable();
  }

  void Update()
  {
    var primaryTouch = m_PointerInput.Default.PrimaryPointer.ReadValue<VisionOSSpatialPointerState>();
    var phase = primaryTouch.phase;

    if (phase == VisionOSSpatialPointerPhase.Began)
    {
      var rayOrigin = primaryTouch.startRayOrigin;
      var rayDirection = primaryTouch.startRayDirection;
      var ray = new Ray(rayOrigin, rayDirection);
      var hit = Physics.Raycast(ray, out var hitInfo, Mathf.Infinity);

      if (hit)
      {
        // 获取射线碰撞到的对象
        GameObject hitObject = hitInfo.collider.gameObject;
        // 检查是否点击了Button
        Button button = hitObject.GetComponent<Button>();
        if (button != null)
        {
          // 执行按钮点击后的逻辑
          button.onClick.Invoke();
        }
      }
    }
  }
}

3.3 运行

视频地址

Unity 开发 VisionOS 游戏初探

3.3 MR 应用

3.3.1 安装 PolySpacial

​ 开始 MR 项目前,需先安装其相关依赖包,分别为:com.unity.polyspatial、 com.unity.polyspatial.visionos、 and com.unity.polyspatial.xr。

Unity 开发 VisionOS 游戏初探

3.3.2 配置 PolySpatial

​ 菜单栏 Edit -> Project Settings -> XR Plugin-in Management -> Apple visionOS,App Mode 设置为 “Mixed Reality – Volume or Immersive Space”。

Unity 开发 VisionOS 游戏初探

​ 菜单栏 Edit -> Project Settings -> PolySpatial,启用 PolySpatial 运行时。

Unity 开发 VisionOS 游戏初探

3.3.3 准备

​ 目前来看,有边界的 MR 应用场景面幅较小,如果将“糖果大作战”进行 MR 改造,虚拟人 Avatar 将尺寸更小,操作难度陡增(虽然模拟器内可以放大视角后操作)。所以在 MR 项目探索中,选择官方素材进行学习与改造。

​ 在 3.3.2 安装 Polyspatial 时,可以看到其拥有 Samples,选择 Import “Unity PolySpatial Samples”,其已配备体积相机基础设置及多个展示实例。

Unity 开发 VisionOS 游戏初探

​ 当然,也可以自行添加体积相机配置及组件。Scene -> Overlays -> XR Building Blocks -> Volume Camere,会自动生成体积相机配置文件。

Unity 开发 VisionOS 游戏初探

​ 随后创建空物体,添加体积相机组件,并挂载前面创建的配置文件即可。

Unity 开发 VisionOS 游戏初探

​ 此时,可以选择创建有界(Bounded)应用或无界(Unbounded)应用。

⚠️ 有界应用的场景内容布局必须在限制范围内,超出将无法显示。

Unity 开发 VisionOS 游戏初探

3.3.4 核心代码

​ 除去游戏玩法核心代码外,更多的重点需要放到交互触发上。依托于 Unity 的 Input System, 在 Apple Vision Pro 模拟器中,采用点击方式触发,而在真实设备中,则是采用自动识别 “捏手”手势触发。

代码:

using Unity.PolySpatial.InputDevices;
using UnityEngine;
using UnityEngine.InputSystem.EnhancedTouch;
using UnityEngine.InputSystem.LowLevel;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
using TouchPhase = UnityEngine.InputSystem.TouchPhase;

namespace GameContent
{
    public class GameContentInputManager : MonoBehaviour
    {
        void OnEnable()
        {
            EnhancedTouchSupport.Enable();
        }

        void Update()
        {
            var activeTouches = Touch.activeTouches;

            if (activeTouches.Count > 0)
            {
                var primaryTouchData = EnhancedSpatialPointerSupport.GetPointerState(activeTouches[0]);
                if (activeTouches[0].phase == TouchPhase.Began)
                {
                    // 允许用戳或间接捏来打破气球
                    if (primaryTouchData.Kind == SpatialPointerKind.IndirectPinch || primaryTouchData.Kind == SpatialPointerKind.Touch)
                    {
                        var balloonObject = primaryTouchData.targetObject;
                        if (balloonObject != null)
                        {
                            if (balloonObject.TryGetComponent(out BalloonBehavior balloon))
                            {
                                // 打破气球操作
                            }
                        }
                    }
                }
            }
        }
    }
}

3.3.5 运行

视频地址

Unity 开发 VisionOS 游戏初探

3.4 Windowed 应用

​ 当未启用 XR 相关配置时,Uniy 默认导出 visionOS 常见桌面应用程序,本文不再赘述。

3.5 导出

​ 菜单栏 File -> Build And Run,此时 Unity 会将项目编译打包为 Reality 能识别的数据文件,并调用 XCode 进行编译生成。经过漫长的等待,XCode 将自动开启 Apple Vision Pro 模拟器打开项目。

3.4.1 VR 应用

视频地址

Unity 开发 VisionOS 游戏初探

3.4.2 MR 应用

视频地址

Unity 开发 VisionOS 游戏初探

4 实时预览

​ 每次在 Unity 中修改或完成某功能后,为了查看在实际效果,都需要经历重新编译文件、运行 XCode 等漫长的过程,那么?有没有可以实时预览的方法呢?Play to Device Host

​ 在 Appele VisionOS Pro 模拟器或真机设备启动 Play to Device Host 后,Uniy Play 的任何修改都将实时同步到模拟器/真机设备,而模拟器/真机设备执行的任何交互也都将同步回到 Unity 编辑器。

此功能仅 MR 适用。

4.1 安装

  • 在 Appele VisionOS Pro 模拟器中,下载解压后拖入模拟器安装。
  • 在 Appele VisionOS Pro 真机设备中,安装 TestFlight 并加入 Play to Device Host 安装。

Unity 开发 VisionOS 游戏初探

4.2 配置

​ 配置前,确保 Unity 编辑器与 Appele VisionOS Pro 模拟器/真机设备处于同一网络环境。

  • 在 Appele VisionOS Pro 模拟器/ 真机设备中,打开 Play to Device Host,查看需要连接的 IP 地址。

    Unity 开发 VisionOS 游戏初探

  • Unity 编辑器内,菜单栏 Window -> PolySpatial -> Play to Device。勾选 Connect To Player on Play Mode 并输入上述 IP 地址。

    Unity 开发 VisionOS 游戏初探

4.3 使用

​ 此时,Unity 编辑器中启动 Play,便可以在 Appele VisionOS Pro 模拟器/真机设备中实时预览了。

Unity 开发 VisionOS 游戏初探

5 总结

​ 诚然,Unity visionOS 目前仍处于 Beta 阶段,在探索过程会发现不少功能缺失与 Bug,如无无法设置应用图标、VR 场景开屏黑框、重复编译有概率程序报错、网络请求导致程序 Crash 等问题。

​ 但瑕不掩瑜,目前通过相关依赖包已能完成大部分应用开发与模拟器操作,整体开发流程与日常 Unity 游戏开发基本无异。相信随着版本的更新,Unity 开发者将拥有更加丝滑与完备的开发体验。

6 相关链接

Apple VisionOS: developer.apple.com/visionos

Unity VisionOS: create.unity.com/spatial

原文链接:https://juejin.cn/post/7325495635456983050 作者:郝海友

(0)
上一篇 2024年1月19日 下午4:16
下一篇 2024年1月19日 下午4:27

相关推荐

发表回复

登录后才能评论