Overview
After creating a Reality Composer project, then we can add the 3D content to ARView by calling this code
if let boxScene = try? Experience.loadBox() {
arView.scene.anchors.append(boxScene)
}
By calling the code above, the scene will be automatically spawned at the ray of center view.
Expected
To make the user feel natural, the App will spawn at the user's tap position. To do so, I started by getting a tap position
Get a tapped position
let arView = ARView()
context.coordinator.arView = arView
// Register tap gesture
let tapGesture = UITapGestureRecognizer(target: context.coordinator,
action:#selector(context.coordinator.tapped(sender:)))
arView.addGestureRecognizer(tapGesture)
//...
@objc func tapped(sender: UITapGestureRecognizer) {
// Get tap position
let tapPosition = sender.location(in: arView)
// call `spawnBoxAt(_)` to spawn a box a ray of user's tap position
spawnBoxAt(tapPosition)
}
spawnBoxAt(tapPosition)
Experience.loadArrowDownAsync { [weak self] result in
guard let arrowDownScene = try? result.get() else { return }
// Perform a raycast
if let ray = self?.arView.ray(through: tapPosition),
let results = self?.arView.scene.raycast(origin: ray.origin,
direction: ray.direction,
query: .nearest) {
// Get the hit against a SceneUnderstanding
let hitSceneUnderstands = results.filter{ $0.entity is HasSceneUnderstanding }
guard let hitFirst = hitSceneUnderstands.first else { return }
let point = hitFirst.position
// Set position
arrowDownScene.setPosition(point, relativeTo: nil)
self?.arView.scene.anchors.append(arrowDownScene)
arrowDownScene.setPosition(point, relativeTo: nil)
}
}
Unfortunately, the result of this code arrowDownScene.position
is equal to point
that was from hitFirst.position
but the object is not spawned at tap position but still be at the ray of center view