Vision Pro开发实践(一)

news2024/12/28 18:32:48

简介

Vision Pro是苹果公司的首款头戴式“空间计算”显示设备,于2023年6月6日在“WWDC2023”正式发布,同时推出的还有专为Vision Pro打造的操作系统平台visionOS,以及一整套“新的”开发工具,之所以打引号,是因为用于Vision Pro开发的工具和编程语言并没有多少改变,而更多的是需要开发者的开发思维变化。

最近公司组织了几批人员,前往苹果实验室实地体验Vision Pro,并在现场进行适配调试。我有幸参与其中,现在就把整个过程的体验分享给大家,同时分享一些visionOS开发的基础。



别具一格的交互

要了解Vision Pro上应用的适配与开发,就要先了解它的人机交互方式。现在市面上大多数的VR设备采用的都是通过手柄进行指向、选择和点击的操作,辅以识别简单的手势(比如左右滑动等)和头部活动(点头、摇头等)。这样的交互方式最大的优点就是可以降低成本,手柄的制造工艺已经相当成熟,内置陀螺仪和红外感应、NFC元件都不是什么难事,同时减少VR设备的传感器数目从而降低重量,延长续航。

但是苹果显然认为这种交互方式不够理想,如果体验过其他苹果产品就会发现,苹果的设计师似乎一直倾向于利用用户自己的身体来实现目标需求,指纹识别,面部识别,多指手势以及“嘿,Siri”都是一贯如此。而在Vision Pro上,苹果认为用户的眼睛和手完全就可以胜任手柄的工作,所以他们提出的交互方式是别具一格的“眼球追踪+手势识别”。

苹果通过遍布Vision Pro眼部周围的传感器,实现了精读极高的眼球追踪技术:



这样一来,用户的眼睛就变成了鼠标的指针,想要选中哪个元素,只要看向它就可以了。就我实际的体验而言,精度和准确率都非常之高,就连非常小的UI元素都可以准确的选中:

不止如此,苹果还通过Vision Pro下面的一圈传感器进行手势的收集和识别:



苹果下了这么大的血本只为了一个目的:无论用户的手放在哪里,都可以实现高精度的手势识别,面前,腿上,沙发上都可以。在首次开机的学习引导里,苹果给出的提示语就能非常好的概括:“you can place your hands wherever you feel comfortable”

除了不限位置,Vision Pro还可以准确的识别单击、捏住和双手手势:



Tap:同时点击拇指和食指,表示点击显示屏上的虚拟元素,相当于点击iPhone的屏幕。

Double Tap:双击手势。

Pinch and Hold:类似于点击并按住手势,执行突出显示文本等操作。

Pinch and Drag:可用于滚动和移动窗口。您可以水平或垂直滚动,如果用户加快手势速度,交互界面也会相应地调整速度。

Zoom:双手手势之一,可以把手指捏在一起,通过拉开手势进行放大,窗口大小也可以通过在角落拖动来调整。

Rotate:另一个双手手势之一,它将涉及将手指捏在一起并旋转双手以操纵虚拟对象。

虽然乍一看起来通过眼球追踪和手势识别来进行日常的操作比较繁琐,你要先看着想要点击的地方,再捏一下手指,但实际体验下来整个过程非常流畅、自然,没有违和感,与苹果生态一贯的操作习惯一脉相承,基本不需要额外的学习成本。但是这种便利的代价也很明显:大量的传感器增加了设备的成本(3w+)和重量(600-650g),同时即便是连接外接电池,最长也只能实现2小时的续航时间。

现在还无法断言苹果这套交互方案和手柄对比谁好谁坏,但是正如以往苹果率先提出的“触屏取代实体键盘”,“触摸板手势”以及“全面屏交互”等方案,经过长时间的市场检验,最终还是别广大厂商采用并效仿,这一次苹果在Vision Pro上提出的这套全新的“空间交互方案”日后很有可能成为VR设备采用的主流方案。

移植的适配逻辑

不少研发同学都会有疑问:我的APP没有单独对Vision Pro做过适配,那么它能直接在Vision Pro上运行吗?可以的话它原始的适配逻辑又是什么?

首先对于第一个疑问,答案是肯定的,就算没有经过任何适配,app依然可以在Vision Pro上正常运行,所有的交互都能执行,甚至可以通过盯住屏幕左侧用捏住并拖拽实现“左划返回”手势。

至于原始适配逻辑,如果有曾经在 iPad,或者M系列芯片 Mac电脑上运行手机App的经验,就能大致明白他们在Vision Pro上的适配逻辑了,就是在屏幕上创建一个手机屏幕大小的“模拟器”,让app在上面运行。这里以我们“京东到家”的app为例



当然,如果app做过iPad的适配,那么在Vision Pro上的展示样式则会优先展示为iPad的样式,比如京东主站app:

同时,在App下端会展示两个控制元素,一个小圆点和一个横条。眼睛看向小圆点的话,它会变成一个叉号,用于关闭App(退至后台),需要完全杀死App的话,逻辑则类似于Mac电脑的杀死进程,需要同时按住Vision Pro的返回键和表冠2秒,然后再应用列表中找到 App强制结束



那既然不需要适配也可以正常运行,我们是不是就不需要单独进行VisionOS的开发了呢?当然不是。未经适配的App虽然能够正常运行,但是它的展示样式毕竟是为了手机端而设计的,在Vision Pro上,屏幕从2D的平面拓展到了3D的空间,而在“空间”中,Vision Pro更着重于凸显“无界”的概念:

苹果更倾向于让App没有边界,不局限于手机屏幕的条条框框中,更加融入到空间之中,同时visionOS也允许UI元素超出App的界面边界。所以对于Vision Pro的适配,更多的是从平面到空间的思维转变,如何让App在“空间”这一画布上更好地呈现设计者想要表达的意图才是重中之重。要进行“空间计算”开发,就要了解基础的visionOS开发机制,下面我将介绍一些入门的知识。

开发从入门到略懂

首先,在Xcode15中创建app时,除了以前的iOS、macOS等平台,现在可以选择visionOS平台进行开发,此时SwiftUI提供了许多专为Vision Pro准备的新API,以供空间应用开发。



选择visionOS平台后,可以设置场景类型和氛围样式:



场景类型

visionOS的app中可以创建三种场景类型:

Window形式

主要用于展示2D内容,iPhone和iPad的App在Vision Pro中展示默认就是采用这种形式,如果app需要展示文本内容、视频或者弹窗等等,可以创建这种场景来进行展示。Window形式也可以展示3D元素,但是无法在空间中360度的查看3D模型,因为Window在空间中是以类似于镜子的形态呈现,绕到后面时只能看到白色半透明的面板。

Volumes形式



苹果官方描述说这是最适合展示3D模型的场景,当在app中创建了Volumes类型的场景时,visionOS会开辟出一个3D的空间用于放置3D元素,如果我们想要放置商品的3D模型进行全景展示,可以创建这种场景

Spaces形式



在这种场景下,visionOS会将使用者周围全部设置为可以放置UI元素的区域,周围的所有空间都可以作为开发者的“画布”,你可以在任意位置放置2D、3D模型。但是需要注意的是这种场景理论上只应创建一个。

氛围样式

氛围样式是app的呈现形式,分为.mixed, .progressive,.full三种,我们可以通过一个图来清晰明了的理解它们分别代表的意思:

在工程当中也可以通过代码来进行设置,以实现在不同氛围之间切换:

@main
struct MyImmersiveApp: App {
    @State private var currentStyle: ImmersionStyle = .full


    var body: some Scene {
        WindowGroup() {
            ContentView()
        }


        // Display a fully immersive space.
        ImmersiveSpace(id: "solarSystem") {
            SolarSystemView()
        }.immersionStyle(selection: $currentStyle, in: .mixed, .progressive, .full)
    }
}

风格适配

既然app是在Vision Pro的空间中展示,那么最好可以遵循Vision Pro统一的样式风格,比如:

圆角,毛玻璃半透明的背景

悬停效果



这里说一下悬停效果,它指的是眼睛停留在某个UI元素上时的效果。如果不进行适配,在Vision Pro上运行app,眼睛看向一个可以点击的元素时,它会被高亮显示:





但是苹果似乎觉得这样简单粗暴的悬停效果不够高雅,所以提供了hoverEffect属性让我们可以自定义悬停效果:





这样设置后,眼睛停留在元素上时,我们可以实现高亮、突出、改变圆角等效果,而且高亮点会随着眼睛盯的点而改变,非常神奇。



超出边界外布局

在visionOS app中,为了提高场景的沉浸感,苹果允许把导航栏、tab栏和工具栏等内容无关的元素设置到界面外,并且给他们起了一个独特的名字:ornament。使用系统自带的UIHostingOrnament:





当然也可以自定义,将原来的导航栏等元素改造成ornament:

改造前

struct ContentView: View {
    @State private var selection: AppScreen = .backyards
    var body: some View {    
        NavigationSplitView {
            AppSidebarList(selection: $selection)
        } detail: {
            AppDetailColumn(screen: selection)
        }
    }
}

改造后

struct ContentView: View {
    @State private var selection: AppScreen = .backyards
    var body: some View {    
        View()
            .ornament(visibility: isGoalPanelVisible,
                      attachmentAnchor: .scene(.bottom),
                      contentAlignment: .center) {
                NavigationSplitView {
                    AppSidebarList(selection: $selection)
                } detail: {
                    AppDetailColumn(screen: selection)
                }
            }
    }
}

添加3D模型

visionOS使用了苹果布局多年的RealityKit,结合SwiftUI,从而使得加载3D和2D模型就像加载一张本地资源图片一样方便:

struct SphereView: View {
    @State private var scale = false


    var body: some View {
        RealityView { content in
            if let earth = try? await ModelEntity(named: "earth") {
                content.add(earth)
            }
        } update: { content in
            if let earth = content.entities.first {
                earth.transform.scale = scale ? [1.2, 1.2, 1.2] : [1.0, 1.0, 1.0]
            }
        }
        .gesture(TapGesture().targetedToAnyEntity().onEnded { _ in
            scale.toggle()
        })
    }
}

代码中RealityView就是专门用来展示模型资源的视图,就如同UIImageView加载图片一样,使用ModelEntity就可以很方便的加载本地的模型资源,并设置碰撞体积CollisionComponent和旋转缩放等等

需要注意的是苹果目前仅支持USDZ格式的模型,苹果给出了几个非常精美的模型资源以供下载:

快速查看图库 - 增强现实 - Apple Developer

另外我找到了几个可以免费下载USDZ格式资源的网站:

https://www.cgtrader.com/zh-cn/3d-models/ext/usdz

USDz模型-下载usdz文件| TurboSquid

与业务结合的实践

我们在进行实际业务场景适配的时候,如果是全新的Vision Pro app,则首先要判断当前平台是否是visionOS,如果是像我们一样基于iPad app进行改造,那么要判断是否是iPad设备,我们所采用的机型判断方法为:

func osType() {
     if UIDevice.current.userInterfaceIdiom == .phone {
         print("This code is running on iPhone")
     } else if UIDevice.current.userInterfaceIdiom == .pad {
         print("This code is running on iPad")
     } else if UIDevice.current.userInterfaceIdiom == .vision {
         print("This code is running on Vision Pro")
     }
 }

以我们零售app的适配设计为例,是基于iPad app进行改造,为了获得更好的展示效果,需要针对宽屏做UI改造:

iPhone设计稿:



iPad设计稿:

除了上文中提到的悬停效果等改造,资源位宽度,间距和排布等要素也需要进行相应的改变,来适配iPad或者Vision Pro更宽阔的视野。我们的Feeds展示场景,入口求部分氛围中配置的楼层背景图拉伸,并根据设计稿进行适配;为你推荐资源位一行二的展示样式改为为一行四,在用户使用时能够获得更好的视觉体验。

本篇暂时就先介绍到这里,后续会有更多Vision Pro适配和空间开发的文章,希望能帮助大家在即将到来的这场“空间计算战斗”先拔头筹。

作者:零售前台研发 姜海

来源:京东零售技术 转载请注明来源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1564025.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Taro多行文本最多展示5行,超出“查看更多”展示,点击弹层

Taro中,页面需求: 多行文本,展示最多展示5行,超出5行,展示“查看更多”按钮,点击弹层展示文本详细信息。 弹层代码就不说了,着重说一下怎么获取区域高度~ 1.区域设置max-height&am…

【AI绘画/作图】风景背景类关键词模板参考

因为ds官网被墙,所以翻了IDE的源码整理了下stablestudio里的官方模板,顺便每个模板生成了一份…不知道怎么写关键词的可以参考 Stunning sunset over a futuristic city, with towering skyscrapers and flying vehicles, golden hour lighting and dramatic cloud…

java的警示之有危险的行为

👨‍💻作者简介:👨🏻‍🎓告别,今天 📔高质量专栏 :☕java趣味之旅 欢迎🙏点赞🗣️评论📥收藏💓关注 💖衷心的希…

ssm016基于 Java Web 的校园驿站管理系统+jsp

校园驿站管理系统的设计与实现 摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对校园快递信息管理混乱,出…

类和对象的下篇

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary_walk ⸝⋆ ━━━┓ - 个性标签 - :来于“云”的“羽球人”。…

从零实现一个Http服务器

HttpServer HTTPServer项目是一个基于C编写的简单的HTTP服务器实现,用于处理客户端的HTTP请求并提供相应的服务。该项目使用了Socket编程来实现服务器与客户端之间的通信,通过监听指定的端口并接受客户端连接,然后解析HTTP请求并生成对应的H…

新版Pubmed初识

PubMed基本检索操作指南。 PubMed和MEDLINE MEDLINE是美国国立医学图书馆(The National Library of Medicine,NLM)开发的国际性综合生物医学信息书目数据库,是当前国际上最权威的生物医学文献数据库。内容包括美国医学索引&…

通过提交容器的方式修改ubuntu镜像的apt源

通过提交容器的方式修改ubuntu镜像的apt源 步骤总结 问题,每次创建容器之后,都要在容器内手动更改镜像源。 不如,干脆修改镜像的apt源,一次到位。 步骤 先创建一个容器,到容器内执行变更命令。 D:/sandbox> dock…

Sora 基础作品之 DiT:Scalable Diffusion Models with Transformer

Paper name Scalable Diffusion Models with Transformers (DiT) Paper Reading Note Paper URL: https://arxiv.org/abs/2212.09748 Project URL: https://www.wpeebles.com/DiT.html Code URL: https://github.com/facebookresearch/DiT TL;DR 2022 年 UC Berkeley 出…

vue 移动端弹窗带滚动效果 滚动到底的时候弹窗下的页面会跟着滑动

<template><div class"wrap" :style"dynamicStyle"><!--dynamicStyle主要是介个 通过computed设置postion的值 弹窗的时候设置为fixed 关闭弹窗的时候设置为unset--><div class"banner-wrap"><img src"/assets/…

C语言一维数组及二维数组详解

引言&#xff1a; 小伙伴们&#xff0c;我发现我正文更新的有些慢&#xff0c;但相信我&#xff0c;每一篇文章真的都很用心在写的&#xff0c;哈哈&#xff0c;在本篇博客当中我们将详细讲解一下C语言中的数组知识&#xff0c;方便大家后续的使用&#xff0c;有不会的也可以当…

ArcGIS Pro打不开Excel?Microsoft驱动程序安装不上?

刚用ArcGIS pro的朋友们可能经常在打开xls或者xlsx文件的时候都会提示&#xff0c;未安装所需的Microsoft驱动程序。 怎么办呢&#xff1f;当然&#xff0c;按照提示装一下驱动就会好吗&#xff1f;有什么状况会出现&#xff1f;有什么临时替代方案呢&#xff1f; 全文目录&a…

ssm017网上花店设计+vue

网上花店的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管理就很关…

C++ 哈希思想应用:位图,布隆过滤器,哈希切分

C 哈希思想应用:位图,布隆过滤器,哈希切分 一.位图1.位图的概念1.问题2.分析3.位图的概念4.演示 2.位图的操作3.位图的实现1.char类型的数组2.int类型的数组3.解决一开始的问题位图开多大呢?小小补充验证 4.位图的应用1.给定100亿个整数&#xff0c;设计算法找到只出现一次的整…

【Redis】NoSQL之Redis的配置和优化

关系型数据库与非关系型数据库 关系型数据库 关系型数据库是一个结构化的数据库&#xff0c;创建在关系型模型&#xff08;二维表&#xff09;的基础上&#xff1b;一般面向于记录&#xff1b; SQL语句(标准数据查询语句)就是一种基于关系型数据库的语言&#xff0c;用于执行…

转圈游戏(acwing)

题目描述&#xff1a; n 个小伙伴&#xff08;编号从 0 到 n−1&#xff09;围坐一圈玩游戏。 按照顺时针方向给 n 个位置编号&#xff0c;从 0 到 n−1。 最初&#xff0c;第 0 号小伙伴在第 0 号位置&#xff0c;第 1 号小伙伴在第 1 号位置&#xff0c;…

FastAPI Web框架教程 第14章 部署

14-1 在Linux上安装Python 【环境】 腾讯云服务器 Centos 8 【安装方式】 源码编译安装 安装步骤&#xff1a; 第1步&#xff1a;更新yum源 cd /etc/yum.repos.d/ sed -i s/mirrorlist/#mirrorlist/g /etc/yum.repos.d/CentOS-* sed -i s|#baseurlhttp://mirror.centos.…

SV学习笔记(一)

SV&#xff1a;SystemVerilog 开启SV之路 数据类型 內建数据类型 四状态与双状态 &#xff1a; 四状态指0、1、X、Z&#xff0c;包括logic、integer、 reg、 wire。双状态指0、1&#xff0c;包括bit、byte、 shortint、int、longint。 有符号与无符号 &#xff1a; 有符号&am…

ObjectiveC-03-XCode的使用和基础数据类型

本节做为Objective-C的入门课程&#xff0c;笔者会从零基础开始介绍这种程序设计语言的各个方面。 术语 ObjeC&#xff1a;Objective-C的简称&#xff0c;因为完整的名称过长&#xff0c;后续会经缩写来代替&#xff1b;项目/工程&#xff1a;也称工程&#xff0c;指的是一个A…

记某客户的一次无缝数据迁移

背景 客户需要将 Elasticsearch 集群无缝迁移到移动云&#xff0c;迁移过程要保证业务的最小停机时间。 实现方式 通过采用成熟的 INFINI 网关来进行数据的双写&#xff0c;在集群的切换恢复过程中来记录数据变更&#xff0c;待全量数据恢复之后再追平后面增量数据&#xff…