问题
What I want to achieve: Attach a sphere to the camera position (so that it always stay at the center of the screen as the device move) and detect when it is on top of other AR objects - to trigger other actions/behaviour on the AR objects.
Approach: I have created the sphere and attached to the center of the screen as shown below
@IBOutlet var arView: ARView!
override func viewDidLoad() {
super.viewDidLoad()
let mesh = MeshResource.generateSphere(radius: 0.1)
let sphere = ModelEntity(mesh: mesh)
let anchor = AnchorEntity(.camera)
sphere.setParent(anchor)
arView.scene.addAnchor(anchor)
sphere.transform.translation.z = -0.75
}
Next step, perform a hittest or a raycast in session(_:didUpdate:)
let results = arView.hitTest(CGPoint(x: 0.5, y: 0.5), query: .all, mask: .default)
//normalised center ; 2D position of the camera (our sphere) in the view’s coordinate system
But I am constantly getting ground plane as my result with this approach. Is there something I am missing or there is a different approach to achieving this
Note: Just in case there is something wrong I have created my basic scene as I want to track an image and add content on top of the image marker in Reality Composer and using the .rcproject in Xcode also have enabled collision property for all the overlaid items.
回答1:
Try the following solution:
import ARKit
import RealityKit
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
var sphere: ModelEntity?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = arView.center
let results: [CollisionCastHit] = arView.hitTest(touch)
if let result: CollisionCastHit = results.first {
if result.entity.name == "Cube" && sphere?.isAnchored == true {
print("BOOM!")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Crosshair
let mesh01 = MeshResource.generateSphere(radius: 0.01)
sphere = ModelEntity(mesh: mesh01)
sphere?.transform.translation.z = -0.15
let cameraAnchor = AnchorEntity(.camera)
sphere?.setParent(cameraAnchor)
arView.scene.addAnchor(cameraAnchor)
// Model for collision
let mesh02 = MeshResource.generateBox(size: 0.3)
let box = ModelEntity(mesh: mesh02, materials: [SimpleMaterial()])
box.generateCollisionShapes(recursive: true)
box.name = "Cube"
let planeAnchor = AnchorEntity(.plane(.any,
classification: .any,
minimumBounds: [0.2, 0.2]))
box.setParent(planeAnchor)
arView.scene.addAnchor(planeAnchor)
}
}
来源:https://stackoverflow.com/questions/65814249/implement-a-crosshair-kind-behaviour-in-realitykit