Реальность Composer - Пользовательское столкновение между сущностями разных сцен - PullRequest
1 голос
/ 12 февраля 2020

Я довольно новичок в RealityKit и ARKit. У меня есть две сцены в реальности 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
}

1 Ответ

1 голос
/ 12 февраля 2020

Сцена 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 scene

А вот как ваш код должен выглядеть , если вы используете модели из 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)
    }
}

enter image description here enter image description here

...