Reality Composer - 不同场景实体之间的自定义碰撞 [英] Reality Composer - Custom Collision Between Entities of Different Scenes

查看:27
本文介绍了Reality Composer - 不同场景实体之间的自定义碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm pretty new to RealityKit and ARKit. I have two scenes in Reality Composer, one with a book image anchor and one with a horizontal plane anchor. The first scene with an image anchor has a cube attached to the top of it and the second scene built on a horizontal plane has two rings. All objects have a fixed collision. I'd like to run an animation when the rings and the cube touch. I couldn't find a way to do this in Reality Composer, so I made two attempts within the code to no avail. (I'm printing "collision started" just to test the collision code without the animation) Unfortunately, it didn't work. Would appreciate help on this.

尝试 #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
}

推荐答案

RealityKit 场景

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

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

Let's see what a developer documentation says about it:

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

HasCollision protocol is an interface used for ray casting and collision detection.

如果您在 RealityKit 中生成模型,您的实现应该是什么样子的:

Here's how your implementation should look like if you generate models in 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 中的模型,您的代码应该如下所示:

Reality Composer scene

And here's how your code should look like if you use models from 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 - 不同场景实体之间的自定义碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆