在 iOS 18 中使用 SwiftUI 和 RealityView 实现立体视图或 VR 视图

问题描述 投票:0回答:1

有很多成功的方法可以使用 VR Box 或 Google VR Cardboard 等在横向 iPhone 中制作 2 个屏幕,并将其用作 VR 媒体,所有这些都可以在 SceneKit、ARKit 等中使用 Objective C 和 Swift 进行工作,这要归功于Storyboard 视图允许我们精确分割屏幕并在每个屏幕上应用一个视图,但在 SwiftUI 中没有 Storyboard,所以我们必须跳出框框思考,比如创建一个 HStack 并将其并排放置,它实际上可以工作,但我想知道它是否有效是正确的方法,因为在其他技术中,我们使用共享的 3d 视图来简单地将左侧的内容克隆到右侧,而不用两个相同的代码使系统超载,但在我的试验中,我没有看到这一点,所以可能有什么东西可以解决这个问题。 以下是我从我卑微的经历中得到的注意到:

第一个问题:两侧没有连接在一起,这意味着当左侧视图上的 3D 项目移动时,我看不到右侧的项目以相同的方式移动或根本没有移动

第二个问题:即使有基本的动画,模型本身也非常慢,即使在真正的 iPhone 设备上,它实际上也是滞后的。

第三个问题:处理安全区域的解决方案是什么,在最新的 iPhone 上,我可以通过隐藏黑色背景的安全区域,将两个对象很好地居中在 Storyboard 中,并将整个屏幕移离它一点,然后将两个对象分开剩余宽度为 2 并进行计算,但是我应该在 HStack 中推入多少以避免安全区域并保持两个视图居中?

无论如何,这是我到目前为止的代码,

import SwiftUI
import RealityKit

struct ContentView: View {
  @State var box = AnchorEntity()
  @State var box2 = AnchorEntity()

  @State private var rotateTime: Timer!

  @State var rotateCounter: Float = 0.0

  var body: some View {
    
    HStack {
        RealityView{ content in
            
            let item = ModelEntity(mesh: .generateBox(size: .init(0.5, 0.5, 0.5)), materials: [SimpleMaterial(color: .white, isMetallic: false)])
            box.addChild(item)
            // rotate box on x and y 45 degrees
            box.transform.rotation = simd_quatf(angle: .pi / 4, axis:[0,1,1])

            content.add(box)
        }

        RealityView{ content in
            content.add(box.clone(recursive: true))
        }

    }
    .background(.black)
    .onAppear(){
        
        // After 5 Sec the animation starts
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0)
        {
            //-- Run Rotation Loop ----
            rotateTime?.invalidate() // to make sure no instance for it before
            
            rotateTime = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true, block: { _ in
                rotateMe()
            })
        }
    }
}

func rotateMe(){
    
    rotateCounter += 1
    
    if rotateCounter > 360 {
        rotateCounter = 0.0
    }

    box.transform.rotation = simd_quatf(angle: (rotateCounter * (.pi / 180)), axis: [0,1,0])
  }
}

当代码启动时,它将等待 5 秒,然后开始尝试左视图框的动画 enter image description here

enter image description here

swift swiftui virtual-reality realitykit realityview
1个回答
0
投票

如果每个锚实体都是唯一的,一切都会正常工作。

此外,

iOS 18
/
iPadOS 18
模拟器无法正常工作。

使用设备!

import SwiftUI
import RealityKit

struct ContentView : View {
    @State var anchor1 = AnchorEntity()
    @State var anchor2 = AnchorEntity()
    @State var rotateTime: Timer!
    @State var rotateCounter: Float = 0.0

    var body: some View {
        HStack {
            RealityView { rvc in
                let item = ModelEntity(mesh: .generateBox(size: 0.5), 
                                  materials: [SimpleMaterial()])
                anchor1.addChild(item)
                anchor1.orientation = .init(angle: .pi/4, axis:[0,1,1])
                rvc.add(anchor1)
            }
            RealityView { rvc in
                let item = ModelEntity(mesh: .generateBox(size: 0.5), 
                                  materials: [SimpleMaterial()])
                anchor2.addChild(item)
                anchor2.orientation = .init(angle: .pi/4, axis:[0,1,1])
                rvc.add(anchor2)
            }
        }
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
                rotateTime?.invalidate()
                rotateTime = Timer.scheduledTimer(
                    withTimeInterval: 0.01, repeats: true, block: { _ in
                        rotate(anchor1)
                        rotate(anchor2)
                    }
                )
            }
        }
        .background(.black)
    }
    func rotate(_ anchor: AnchorEntity) {
        rotateCounter += 1
        
        if rotateCounter > 360 { rotateCounter = 0.0 }
        
        anchor.orientation = .init(angle: (rotateCounter * (.pi/180)), axis: [0,1,0])
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.