问题
My Experience.rcproject
has animations that can be triggered by tap action.
Two cylinders are named “Button 1” and “Button 2” and have Collide turned on.
I am using Async
method to load Experience.Map scene and addAnchor
method to add mapAnchor to ARView in a ViewController.
I tried to run HitTest on the scene to see if the app reacts properly.
Nonetheless, the HitTest result prints the entity name of a button even when I am not tapping on it but area near it.
class augmentedReality: UIViewController {
@IBOutlet weak var arView: ARView!
@IBAction func onTap(_ sender: UITapGestureRecognizer) {
let tapLocation = sender.location(in: arView)
// Get the entity at the location we've tapped, if one exists
if let button = arView.entity(at: tapLocation) {
// For testing purposes, print the name of the tapped entity
print(button.name)
}
}
}
Below is my attempt to add the AR scene and tap gesture recogniser to arView.
class augmentedReality: UIViewController {
arView.scene.addAnchor(mapAnchor)
mapAnchor.notifications.hideAll.post()
mapAnchor.notifications.mapStart.post()
self.arView.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(onTap))
self.arView.addGestureRecognizer(tapGesture)
}
Question 1
How can I achieve the goal of only having the entity name of a button printed when I am really tapping on it instead of close to it?
Question 2
Do I actually need to turn Collide on to have both buttons able to be detected in the HitTest?
Question 3
There’s an installGestures method. There’s no online tutorials or discussions about this at the moment. I tried but I am confused by (Entity & HasCollision). How can this method be implemented?
回答1:
To implement a robust
Hit-Testing
in RealityKit, all you need is the following code:
import RealityKit
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
let scene = try! Experience.loadScene()
@IBAction func onTap(_ sender: UITapGestureRecognizer) {
let tapLocation: CGPoint = sender.location(in: arView)
let result: [CollisionCastHit] = arView.hitTest(tapLocation)
guard let hitTest: CollisionCastHit = result.first
else { return }
let entity: Entity = hitTest.entity
print(entity.name)
}
override func viewDidLoad() {
super.viewDidLoad()
scene.steelBox!.scale = [2,2,2]
scene.steelCylinder!.scale = [2,2,2]
scene.steelBox!.name = "BOX"
scene.steelCylinder!.name = "CYLINDER"
arView.scene.anchors.append(scene)
}
}
When you tap on entities in ARView a Debug Area prints "BOX" or "CYLINDER". And if you tap anything but entities, a Debug Area prints just "Ground Plane".
If you need to implement a Ray-Casting read this post, please.
P.S.
In case you run this app on macOS Simulator, it prints just Ground Plane
instead of BOX
and CYLINDER
. So you need to run this app on iPhone.
来源:https://stackoverflow.com/questions/56736645/hittest-prints-ar-entity-name-even-when-i-am-not-tapping-on-it