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

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

猜你喜欢

转载自blog.csdn.net/weixin_43233219/article/details/133778314
今日推荐