【问题标题】:Reality Composer - Custom Collision Between Entities of Different ScenesReality Composer - 不同场景实体之间的自定义碰撞
【发布时间】:2020-05-28 04:02:34
【问题描述】:

我对 RealityKit 和 ARKit 还是很陌生。我在 Reality Composer 中有两个场景,一个带有书籍图像锚点,一个带有水平平面锚点。第一个带有图像锚的场景顶部有一个立方体,第二个构建在水平面上的场景有两个环。所有物体都有固定的碰撞。我想在环和立方体接触时运行动画。我在 Reality Composer 中找不到执行此操作的方法,因此我在代码中进行了两次尝试,但均无济于事。 (我打印“碰撞开始”只是为了测试没有动画的碰撞代码)不幸的是,它没有用。非常感谢这方面的帮助。

尝试 #1:

func makeUIView(context: Context) -> ARView {

    let arView = ARView(frame: .zero)

    let componentBreakdownAnchor = try! CC.loadComponentBreakdown()

    arView.scene.anchors.append(componentBreakdownAnchor)

    let bookAnchor = try! CC.loadBook()
    arView.scene.anchors.append(bookAnchor)   

    let ringsAnchor = try! CC.loadRings()
    arView.scene.anchors.append(ringsAnchor)

    // Add the componentBreakdown anchor to the scene
    arView.scene.anchors.append(componentBreakdownAnchor)

    let bookAnchor = try! CC.loadBook()
    arView.scene.anchors.append(bookAnchor)    

    let ringsAnchor = try! CC.loadRings()
    arView.scene.anchors.append(ringsAnchor)

    let _ = ringsAnchor.scene?.subscribe(
    to: CollisionEvents.Began.self,
    on: bookAnchor
    ) { event in
      print("collision started")
    }

    return arView
}

尝试 #2

func makeUIView(context: Context) -> ARView {

    let arView = ARView(frame: .zero)

    let componentBreakdownAnchor = try! CC.loadComponentBreakdown()

    arView.scene.anchors.append(componentBreakdownAnchor)

    let bookAnchor = try! CC.loadBook()
    arView.scene.anchors.append(bookAnchor)  

    let ringsAnchor = try! CC.loadRings()
    arView.scene.anchors.append(ringsAnchor)

    // Add the componentBreakdown anchor to the scene
    arView.scene.anchors.append(componentBreakdownAnchor)

    let bookAnchor = try! CC.loadBook()
    arView.scene.anchors.append(bookAnchor)   

    let ringsAnchor = try! CC.loadRings()
    arView.scene.anchors.append(ringsAnchor)

    arView.scene.subscribe(
      to: CollisionEvents.Began.self,
      on: bookAnchor

    ) { event in
      print("collision started")
    }

    return arView
}

【问题讨论】:

    标签: swift augmented-reality arkit realitykit reality-composer


    【解决方案1】:

    RealityKit 场景

    如果你想从头开始使用 RealityKit 场景中的模型碰撞,首先你需要实现一个HasCollision 协议。

    让我们看看开发者文档是怎么说的:

    HasCollision协议是用于光线投射和碰撞检测的接口。

    如果您在 RealityKit 中生成模型,您的实现应该如下所示:

    import Cocoa
    import RealityKit
    
    class CustomCollision: Entity, HasModel, HasCollision {
    
        let color: NSColor = .gray
        let collider: ShapeResource = .generateSphere(radius: 0.5)
        let sphere: MeshResource = .generateSphere(radius: 0.5)
    
        required init() {
            super.init()
    
            let material = SimpleMaterial(color: color,
                                     isMetallic: true)
    
            self.components[ModelComponent] = ModelComponent(mesh: sphere,
                                                        materials: [material])
    
            self.components[CollisionComponent] = CollisionComponent(shapes: [collider],
                                                                       mode: .trigger,
                                                                     filter: .default)
        }
    }
    

    Reality Composer 场景

    如果您使用 Reality Composer 中的模型,您的代码应该如下所示:

    import UIKit
    import RealityKit
    import Combine
    
    class ViewController: UIViewController {
    
        @IBOutlet var arView: ARView!
        var subscriptions: [Cancellable] = []
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let groundSphere = try! Experience.loadStaticSphere()
            let upperSphere = try! Experience.loadDynamicSphere()
    
            let gsEntity = groundSphere.children[0].children[0].children[0]
            let usEntity = upperSphere.children[0].children[0].children[0]
    
            // CollisionComponent exists in case you turn on 
            // "Participates" property in Reality Composer app
            print(gsEntity)   
    
            let gsComp: CollisionComponent = gsEntity.components[CollisionComponent]!.self
            let usComp: CollisionComponent = usEntity.components[CollisionComponent]!.self
    
            gsComp.shapes = [.generateBox(size: [0.05, 0.07, 0.05])]
            usComp.shapes = [.generateBox(size: [0.05, 0.05, 0.05])]
    
            gsEntity.components.set(gsComp)
            usEntity.components.set(usComp)
    
            let subscription = self.arView.scene.subscribe(to: CollisionEvents.Began.self,
                                                           on: gsEntity) { event in
                print("Balls' collision occured!")
            }
            self.subscriptions.append(subscription)
    
            arView.scene.anchors.append(upperSphere)
            arView.scene.anchors.append(groundSphere)
        }
    }
    

    【讨论】:

    • 这很有帮助。对于来自 Reality Composer 的模型的示例,当这两个形状发生碰撞时,我如何执行打印到控制台之类的操作?我已经尝试订阅 groundSphere 和 gsEntity 上的碰撞事件`arView.scene.subscribe(to: CollisionEvents.Began.self, on: gsEntity) { event in print("collision started") }`
    • @aspdev91,我用subscribe() 方法添加了行。不要忘记导入组合框架。
    • 有效!非常感谢您的彻底澄清和更新...
    • 谢谢!下一步,如何防止实体相互重叠?这似乎是 AR 的一个非常基本的用例,其中的事情应该“与现实一样”,但不知何故,让它工作起来似乎非常困难......
    • @Silvain,抱歉耽搁了!请将其作为新问题发布!
    猜你喜欢
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 1970-01-01
    • 2023-03-06
    • 2020-10-30
    • 1970-01-01
    • 2012-10-03
    相关资源
    最近更新 更多