【visionOS】从零开始创建第一个visionOS程序

news2024/11/19 4:47:02

前言:本來是看BonjourWeb的,但不自觉被apple visionOS吸引,因为这个概念的产品真的太前沿新颖了。
说不定到时候我会冲一冲~~~先简单学习下嘿嘿

为Apple Vision Pro创建一个新的应用程序和游戏世界。

介绍visionOS

visionOS是苹果Vision Pro的操作系统。将visionOS与熟悉的工具和技术一起使用,为空间计算构建沉浸式应用程序和游戏。

在这里插入图片描述
靓仔,如果你想为visionOS开发软件,那前提是需要一台带有苹果芯片的Mac。这样才可以在使用SwiftUI创建新应用,充分利用visionOS中提供的沉浸感。

另外,如果你有一个现有的iPad或iPhone,将visionOS添加到应用程序的中,可以感受到更好更贴近现实的外观与体验,并添加特定于平台的功能,以创建引人注目的体验。

将你的应用扩展到沉浸式空间

从熟悉的基于窗口的体验开始,向人们介绍您的内容。从那里,添加特定于visionOS的SwiftUI场景类型,如卷和空间。这些场景类型让你融入深度,3D对象和身临其境的体验。

使用RealityKit和Reality Composer Pro构建应用程序的3D内容,并使用RealityView显示它。在身临其境的体验中,使用ARKit将你的内容与人的周围环境整合起来。

在这里插入图片描述

在页面链接中探索新的交互方式

人们可以通过看着一个元素并轻敲手指来选择它。他们还可以使用特定的手势来缩放、拖动、缩放和旋转对象。SwiftUI提供了对这些标准手势的内置支持,所以你的大部分应用输入都依赖于它们。当你想超越标准手势,使用ARKit创建自定义手势。

在这里插入图片描述

潜入特色示例应用程序页面链接

使用Hello World探索所有visionOS应用程序的核心概念。了解如何使用Happy Beam的ARKit检测自定义手势。发现流2D和立体媒体与目的地视频。并学习如何使用RealityKit和现实作曲家Pro与Diorama和Swift Splash构建3D场景。

创建你的第一个visionOS应用

如果你是visionOS的新手,请从新的Xcode项目开始学习平台功能,并熟悉visionOS的内容和技术。当你为visionOS构建应用程序时,SwiftUI是一个很好的选择,因为它可以让你完全访问visionOS的功能。虽然你也可以使用UIKit来构建你的应用程序的一部分,但你需要使用SwiftUI来实现许多平台独有的功能。

为visionOS开发软件需要一台带有苹果芯片的Mac。

在任何SwiftUI应用中,你都可以使用场景将内容放到屏幕上。场景包含要在屏幕上显示的视图和控件。场景还定义了这些视图和控件出现在屏幕上时的外观。在visionOS中,您可以在同一个场景中包含2D和3D视图,并且可以将这些视图呈现在窗口中或作为人的周围环境的一部分。

在这里插入图片描述
图1 有窗的场景
在这里插入图片描述
图2 场景与窗口和3D对象

从一个新的Xcode项目开始,添加一些特性来熟悉visionOS的内容和技术。在模拟器中运行你的应用程序,以验证你的内容看起来像你期望的那样,并在设备上运行它,以看到你的3D内容栩栩如生。

围绕一个或多个场景组织内容,这些场景管理应用程序的界面。每个场景都包含要显示的视图和控件,场景类型决定内容是采用2D还是3D外观。SwiftUI为visionOS添加了3D场景类型,还为所有场景类型添加了3D元素和布局选项。

创建你的Xcode投影页面链接

在Xcode中选择File >新比;项目。导航到模板选择器的visionOS部分,并选择App模板。当出现提示时,为项目指定一个名称以及其他选项。

当创建一个新的visionOS应用程序时,你可以从配置对话框中配置应用程序的初始场景类型。要在初始场景中主要显示2D内容,请选择Window作为初始场景类型。对于主要的3D内容,选择一个Volume。你也可以添加一个沉浸式场景,将你的内容放置在人物的周围环境中。

在这里插入图片描述
当你想要创建3D资产或场景从你的应用程序中显示时,包括一个现实作曲家专业项目文件。使用这个项目文件从原始形状和现有的USDZ资产构建内容。你也可以用它来为你的内容构建和测试自定义的RealityKit动画和行为。

修改现有的窗口页面链接

使用标准的SwiftUI视图构建初始接口。视图为您的界面提供基本内容,您可以使用SwiftUI修饰符自定义视图的外观和行为。例如,.background修饰符在你的内容后面添加了部分透明的色调:

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
               .background(.black.opacity(0.8))
        }


        ImmersiveSpace(id: "Immersive") {
            ImmersiveView()
        }
    }
}

在页面链接中处理视图中的事件

许多SwiftUI视图自动处理交互——你所要做的就是提供在交互发生时运行的代码。你也可以在视图中添加SwiftUI手势识别器来处理点击、长按、拖动、旋转和缩放手势。系统会自动将以下类型的输入映射到你的SwiftUI事件处理代码:
在这里插入图片描述

这张照片显示的是窗户角落里的控件,以及一个人坐在椅子上,双手放在膝盖上的自上而下的叠加视图。

间接的输入。人的眼睛表明了互动的目标。为了开始互动,人们用一只或两只手同时触摸拇指和食指。额外的手指和手部动作定义手势类型。
在这里插入图片描述

图为虚拟3D键盘。这个人的右手敲击着J键。

直接输入。当一个人的手指与屏幕上的项目占据相同的空间时,系统就会报告一个交互。额外的手指和手部动作定义手势类型。
在这里插入图片描述

这张照片显示了一个人的手在桌子上的物理键盘上打字。一个虚拟的建议条显示在物理键盘的上方。

键盘输入。人们可以使用连接的鼠标、触控板或键盘与项目交互、触发菜单命令和执行手势。

构建并运行你的app页面链接

在模拟器中构建并运行你的应用,看看它看起来如何。visionOS的模拟器有一个虚拟背景作为你的应用程序内容的背景。使用键盘和鼠标或触控板在环境中导航并与应用程序交互。

点击并拖动应用程序内容下方的窗口栏,以重新定位窗口在环境中的位置。将指针移动到窗口栏旁边的圆圈上,显示窗口的关闭按钮。将光标移动到窗口的一个角落,以将窗口栏变为调整大小控件。

tips:应用程序不能控制窗口在空间中的位置。系统将每个窗口放置在初始位置,并根据与应用程序的进一步交互更新该位置。

将3D内容添加到应用程序中

为您的visionOS应用程序添加深度和维度,并发现如何将您的应用程序内容融入人的周围环境。

带有立体显示器的设备可以让人们以一种感觉更真实的方式体验3D内容。内容似乎具有真正的深度,人们可以从不同的角度观看它,使它看起来就在他们面前。

在为visionOS构建应用程序时,请考虑如何为应用程序的界面添加深度。该系统提供了几种显示3D内容的方法,包括在现有窗口中,在卷中以及在沉浸式空间中。选择最适合你的应用和你提供的内容的选项。

在这里插入图片描述
在页面链接中增加传统2D窗口的深度

Windows是应用程序界面的重要组成部分。使用visionOS,应用程序自动获得具有visionOS外观和感觉的材料,完全可调整大小的窗口,间距调整为眼睛和手输入,并为您的自定义控件提供高亮显示调整。

根据需要将深度效果合并到自定义视图中,并使用3D布局选项来安排窗口中的视图。

  • 为视图应用shadow(color:radius:x:y:) visualEffect(_:)修饰符。

  • 当有人使用hoverEffect(_:isEnabled:)修饰符查看视图时,抬起或突出显示视图。

  • 使用ZStack布局视图。

  • 动画视图相关的变化与transform3DEffect(_:)

  • 使用rotation3DEffect(_:axis:anchor:anchorZ:perspective:)修饰符旋转视图。

除了给2D视图更多的深度,你也可以添加静态3D模型到你的2D窗口。Model3D视图加载USDZ文件或其他资产类型,并在窗口中以其固有大小显示它。在你的应用中已经有模型数据的地方使用它,或者可以从网络上下载它。例如,购物应用程序可能会使用这种类型的视图来显示产品的3D版本。

显示动态3D场景使用RealityKitin页面链接

RealityKit是苹果公司用于创建3D模型和场景的技术,你可以在屏幕上动态更新。在visionOS中,使用RealityKit和SwiftUI一起无缝耦合应用程序的2D和3D内容。加载现有的USDZ资产或在Reality Composer Pro中创建场景,为您的内容合并动画,物理,灯光,声音和自定义行为。要在你的应用中使用一个Reality Composer Pro项目,把Swift包添加到你的Xcode项目中,并在你的Swift文件中导入它的模块。

在这里插入图片描述
当你准备在界面中显示3D内容时,使用RealityView。这个SwiftUI视图作为你的RealityKit内容的容器,并允许你使用熟悉的SwiftUI技术更新内容。

下面的例子展示了一个使用RealityView来显示3D球体的视图。视图闭包中的代码为球体创建一个RealityKit实体,在球体表面应用纹理,并将球体添加到视图的内容中。

 struct SphereView: View {
    var body: some View {
        RealityView { content in
            let model = ModelEntity(
                         mesh: .generateSphere(radius: 0.1),
                         materials: [SimpleMaterial(color: .white, isMetallic: true)])
            content.add(model)
        }
    }
}

当SwiftUI显示你的RealityView时,它会执行你的代码一次来创建实体和其他内容。由于创建实体的成本相对较高,因此视图只运行一次创建代码。当您想要更新实体的状态时,请更改视图的状态并使用update闭包将这些更改应用于内容。下面的例子使用了一个update闭包来改变球体的大小,当缩放属性的值改变时:

struct SphereView: View {
    var scale = false


    var body: some View {
        RealityView { content in
            let model = ModelEntity(
                         mesh: .generateSphere(radius: 0.1),
                         materials: [SimpleMaterial(color: .white, isMetallic: true)])
            content.add(model)
        } update: { content in
            if let model = content.entities.first {
                model.transform.scale = scale ? [1.2, 1.2, 1.2] : [1.0, 1.0, 1.0]
            }
        }
    }
}

在页面链接中响应与RealityKit内容的交互

处理与RealityKit场景实体的交互:

  • 给你的RealityView附加一个手势识别器,并给它添加targetedToAnyEntity()修饰符。

  • 将一个InputTargetComponent附加到实体或它的父实体上。

  • 向支持交互的RealityKit实体添加碰撞形状。

targetedToAnyEntity()修饰符提供了手势识别器和RealityKit内容之间的桥梁。例如,要识别某人何时拖动实体,可以指定DragGesture并为其添加修饰符。当指定的手势发生在实体上时,SwiftUI执行提供的闭包。

下面的示例将一个点击手势识别器添加到上一个示例中的球体视图中。代码还将InputTargetComponentCollisionComponent组件添加到形状中,以允许交互发生。如果省略这些组件,视图就不会检测到与实体的交互。

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


    var body: some View {
        RealityView { content in
            let model = ModelEntity(
                mesh: .generateSphere(radius: 0.1),
                materials: [SimpleMaterial(color: .white, isMetallic: true)])


            // Enable interactions on the entity.
            model.components.set(InputTargetComponent())
            model.components.set(CollisionComponent(shapes: [.generateSphere(radius: 0.1)]))
            content.add(model)
        } update: { content in
            if let model = content.entities.first {
                model.transform.scale = scale ? [1.2, 1.2, 1.2] : [1.0, 1.0, 1.0]
            }
        }
        .gesture(TapGesture().targetedToAnyEntity().onEnded { _ in
            scale.toggle()
        })
    }
}

在volume链接中显示3D内容

volume是一种窗口类型,它在三个维度上增长,以匹配它所包含的内容的大小。窗口和volume都可以容纳2D和3D内容,并且在许多方面是相似的。然而,窗口剪辑的3D内容从窗口表面延伸得太远,因此对于主要是3D的内容来说,volume是更好的选择。

要创建一个volume,添加一个WindowGroup场景到你的应用程序,并将其样式设置为volumetric。这个样式告诉SwiftUI为3D内容创建一个窗口。在卷中包含您想要的任何2D或3D视图。你也可以使用RealityKit添加一个RealityView来构建你的内容。下面的例子创建了一个带有一些气球的静态3D模型的volume,这些气球存储在应用程序的bundle中:

struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            Model3D("balloons")
        }.windowStyle(style: .volumetric)
    }
}

窗口和体积是显示有限的2D和3D内容的方便方式,但你的应用不能控制内容在人们周围的位置。系统在显示时间设置每个窗口和音量的初始位置。系统还增加了一个窗口条,允许用户重新定位窗口或调整窗口大小。

在这里插入图片描述
在人周围页面链接中显示3D内容

当你需要更多地控制应用内容的位置时,可以将内容添加到ImmersiveSpace中。沉浸式空间为您的内容提供了一个无限的区域,您可以控制空间内内容的大小和位置。在获得用户许可后,您还可以使用ARKit与沉浸式空间将内容整合到他们的周围环境中。例如,您可以使用ARKit场景重建来获得家具和附近物体的网格,并让您的内容与该网格进行交互。

ImmersiveSpace是一种场景类型,您可以与应用程序的其他场景一起创建。下面的例子展示了一个包含沉浸式空间和窗口的应用程序:

@main
struct MyImmersiveApp: App {
    var body: some Scene {
        WindowGroup() {
            ContentView()
        }


        ImmersiveSpace(id: "solarSystem") {
            SolarSystemView()
        }
    }
}

如果你没有在ImmersiveSpace声明中添加样式修饰符,系统将使用混合样式创建该空间。这种样式将你的内容与显示人物周围环境的直通内容一起显示。其他样式允许你在不同程度上隐藏直通。使用immersionStyle(selection:in:)修饰符指定空间支持的样式。如果指定了多个样式,则可以使用修饰符的选择参数在样式之间切换。

需要注意你在使用混合风格的沉浸式场景中包含了多少内容。占据屏幕很大一部分的内容,即使是部分透明的内容,也会阻止人们看到周围环境中的潜在危险。如果你想让人们沉浸在你的内容中,那就用完整的风格来配置你的空间。有关更多信息,请参阅,在您的应用程序中创建完全沉浸式体验。

请记住设置你在ImmersiveSpace中放置的项目的位置。使用修饰符定位SwiftUI视图,使用转换组件定位RealityKit实体。SwiftUI最初将空间的原点放在人的脚上,但可以根据其他事件改变这个原点。例如,系统可能会移动原点以适应SharePlay活动,该活动显示带有空间角色的内容。如果你需要定位SwiftUI视图和RealityKit实体之间的相对位置,使用RealityView的content参数中的方法执行任何需要的坐标转换。

要显示您的ImmersiveSpace场景,请使用openImmersiveSpace操作打开它,该操作从SwiftUI环境中获得。此操作异步运行,并使用提供的信息来查找和初始化场景。下面的例子展示了一个按钮,它打开带有solarSystem标识符的空格:

Button("Show Solar System") {
    Task {
        let result = await openImmersiveSpace(id: "solarSystem")
        if case .error = result {
            print("An error occurred")
        }
    }
}

当一个应用程序呈现一个ImmersiveSpace时,系统会隐藏其他应用程序的内容,以防止视觉冲突。当你的空间可见时,其他应用程序仍然隐藏,但当你关闭它时,它们会返回。如果你的应用程序定义了多个空格,你必须在显示一个不同的空格之前取消当前可见的空格。如果不取消可见空间,那么当您尝试打开另一个空间时,系统将发出运行时警告。

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

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

相关文章

Linux基本指令(1)

Linux基本指令(1) 1.ls指令1.1ls的用法 2. pwd指令3.cd指令3.1 cd3.2补充内容3.3 cd - 指令3.4 cd ~ 指令 4. touch指令4.1stat指令 5.mkdir 指令6.rmdir/rm指令6.1补充内容 7.man指令8.nano 指令9.cat指令10 cp指令11 mv指令12 echo指令12.1 > 输出重…

二叉搜索树--验证二叉搜索树

验证二叉搜索树-力扣 98 题 解题思路:利用二叉树中序遍历的特性:遍历出来的结果是升序的即符合二叉搜索树 对于二叉树中序遍历不是太理解的,作者推荐的小白书:二叉树的初步认识_加瓦不加班的博客-CSDN博客 中序非递归实现 // 解…

抖音小店创业攻略,快速了解这些适合新手经营的类目

抖音小店是抖音平台上的一种新型电商形态,它允许用户在抖音上开设自己的小店,销售自己的商品。抖音小店的开设门槛低,成本也不高,因此很受新手创业者的青睐。那么,下面不若与众将介绍抖音小店中有哪些适合新手创业者经…

卫星影像-航拍影像-数据叠加到AutoCAD

卫星影像-航拍影像-数据叠加到AutoCAD 发布时间:2018-01-17 版权: 同步视频教程:卫星地图_高清卫星地图_卫星地图视频_卫星图像应用到AutoCAD工程设计(套合、叠加、配准) 视频教程:如何选择中央子午线或者…

.NET 8 中的调试增强功能

作者:James Newton-King 排版:Alan Wang 开发人员喜欢 .NET 强大且用户友好的调试体验。您可以在您选择的 IDE 中设置断点,启动已经附加上调试器的程序,逐步执行代码并查看 .NET 应用程序的状态。 在 .NET 8 中,我们致…

cdsn目录处理:```,```# 目录校正

原标题 <small> cdsn目录处理&#xff1a; &#xff0c;中间添加 # 空格 空行后 遇到的底部空行出错&#xff0c;书接上回&#xff0c;处理空行【python查找替换&#xff1a;查找空行&#xff0c;空行前后添加&#xff0c;中间添加 # 空格 空行后遇到的第1行文字&am…

React 组件传 children 的各种方案

自定义组件的时候往往需要传 children&#xff0c;由于写法比较多样&#xff0c;我就总结了一下。 方案列表 1. 类组件1.1 类组件&#xff0c;不使用解构1.2 类组件&#xff0c;使用解构 2. 函数组件2.1 函数组件&#xff0c;不使用解构2.2 函数组件&#xff0c;外部解构2.3 函…

根据前序遍历结果构造二叉搜索树

根据前序遍历结果构造二叉搜索树-力扣 1008 题 题目说明&#xff1a; 1.preorder 长度>1 2.preorder 没有重复值 直接插入 解题思路&#xff1a; 数组索引[0]的位置为根节点&#xff0c;与根节点开始比较&#xff0c;比根节点小的就往左边插&#xff0c;比根节点大的就往右…

WPF 窗口白屏问题分析与初步解决

环境描述 开发环境&#xff1a; Windows 11 Visual Studio 2022 .NET Framework 4.8 目标电脑环境 Windows10 默认包含了 .NET Framework 4.8 现象 编译好的WPF应用程序&#xff0c;是基于 .NET Framework 4.8开发的&#xff0c;在大部分电脑上可以正常使用。在某个客…

Python算法练习 10.11

leetcode 394 字符串解码 给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的&#xff1b;输入字符串中没…

湖南首个,万应低代码软件技术专业校企共建基地落成!

导语 9月开学季&#xff0c;湖南省民族职业学院教育技术学院迎来了近5000名新生&#xff0c;而其中软件技术专业的205名新生尤为引人注目——他们是这个校企共建专业的第一批学生&#xff0c;也是学院软件技术专业新型校企合作的第一批受益者。 湖南首个 万应低代码软件技术…

10_11C++

思维导图 #include <iostream>using namespace std; class Person { private:string name; protected:int age; public:char sex; public:Person() {cout << "父类无参构造函数" << endl;}Person(string n,int a,char s):name(n),age(a),sex(s){co…

[译]Sentry:如何从数据存储中获得更强的一致性

翻译自&#xff1a;How to Get Stronger Consistency Out of a Datastore 地址&#xff1a;https://blog.sentry.io/2019/09/17/how-to-get-stronger-consistency-out-of-a-datastore Sentry的首要工作是接收、解析用户的异常信息。当用户异常信息大量上报时&#xff0c;Sentry…

Linux部署kubeedge 1.4

文章目录 一、机器信息二、环境准备&#xff08;所有节点操作&#xff09;2.1. 修改主机名2.2. 开启路由转发2.3.安装Docker&#xff08;所有节点&#xff09;2.4.部署K8S集群(单机版&#xff0c;云端节点) 2.5.安装Mosquitto&#xff08;只在边缘节点安装)三、安装kubeedge 1.…

数据库基础篇二

函数 约束 概述 概念&#xff1a;约束是作用于表字段上的规则&#xff0c;用于限制存储在表中的数据。目的&#xff1a;保证数据库中数据的正确、有效性和完整性。分类&#xff1a; 外键约束 外键用来让两张表的数据之间建立连接&#xff0c;从而保证数据的一致性和完整性…

2023全国大学生软件测试大赛开发者测试练习题满分答案(PairingHeap2023)

2023全国大学生软件测试大赛开发者测试练习题满分答案&#xff08;PairingHeap2023&#xff09; 题目详情题解代码&#xff08;直接全部复制到test类中即可&#xff09; 提示&#xff1a;该题只需要分支覆盖得分即可&#xff0c;不需要变异得分 题目详情 题解代码&#xff08;…

Kubernetes使用OkHttp客户端进行网络负载均衡

在一次内部Java服务审计中&#xff0c;我们发现一些请求没有在Kubernetes&#xff08;K8s&#xff09;网络上正确地实现负载均衡。导致我们深入研究的问题是HTTP 5xx错误率的急剧上升&#xff0c;由于CPU使用率非常高&#xff0c;垃圾收集事件的数量很多以及超时&#xff0c;但…

linux开发环境下出现Segmentation fault问题排查一

一、检测代码中是否有数组越界情况 更改以上数组为128*60后&#xff0c;正常。确认是数组溢出导致越界。 二、分析&#xff1a;一般情况下打印的字符刚好在50以内&#xff0c;但是在其它状态下测试&#xff0c;数据字符数据增加从而导致溢出 打印命令如下&#xff1a; sprin…

2.线性表——数据结构学习

零个或多个数据元素的有限序列。 有序 &#xff08;每个元素有且只有一个前驱与后继&#xff09; -> 一对一的关系 前驱 &#xff08;第一个元素无前驱&#xff09;后继&#xff08;最后一个元素无后继&#xff09; 有限 线性表元素个数&#xff1a;n (n ≥ \geq ≥ 0)&a…

D1s芯片启动流程(BROM System)分析

1、D1S芯片介绍 2、BROM介绍 &#xff08;1&#xff09;BROM&#xff08;boot rom&#xff09;&#xff1a;存放启动代码的ROM&#xff0c;该ROM一般在芯片内部集成&#xff0c;是芯片上电执行的最开始代码&#xff1b; &#xff08;2&#xff09;BROM里存放的程序主要功能&…