首页 > 解决方案 > 如何让 AnchorEntity.position 与触摸事件对齐

问题描述

我点击屏幕发射激光:

let tap = UITapGestureRecognizer(target: self, action: #selector(fireLaser(_:)))
arView.addGestureRecognizer(tap)

func fireLaser(_ recognizer: UITapGestureRecognizer) {
    
    let anchor = ARAnchor(name: "LaserBeam", transform: arView.cameraTransform.matrix)
    arView.session.add(anchor: anchor)
}

我希望激光到达我实际点击的位置并从那里消失。在touchesBegan我得到hitPosition并最终将其设置为AnchorEntity.position当我像这样放置对象时

if let hitPosition = hitPosition {
    anchorEntity.position = hitPosition
}

问题是我点击屏幕上的激光会转到另一个位置。例如,如果我点击屏幕底部,激光将从屏幕顶部发射并消失在那里,而它应该从底部发生。

我怎样才能让激光到达我点击的地方?

var hitPosition: SIMD3<Float>?

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
    guard let touch = touches.first else { return }
    guard let results = arView.hitTest(touch.location(in: arView), types: [ARHitTestResult.ResultType.featurePoint]) else { return }
    guard let hitTest = results.last else { return }
    
    let transform = hitTest.worldTransform
    let hitPosition = SCNVector3(transform.columns.3.x, transform.columns.3.y, transform.columns.3.z)
    
    let simd3Position = simd_float3(hitPosition)
    
    self.hitPosition = simd3Position
}

func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
    for anchor in anchors {
        if let anchorName = anchor.name, anchorName == "LaserBeam" {
            placeObject(named: anchorName, for: anchor)
        }
    }
}

func placeObject(named entityName: String, for anchor: ARAnchor) {
    
    do {
        
        let laserEntity = try ModelEntity.load(named: entityName)
        
        let anchorEntity = AnchorEntity(anchor: anchor)

        if let hitPosition = hitPosition {
            anchorEntity.position = hitPosition
        }

        anchorEntity.addChild(laserEntity)
        arView.scene.addAnchor(anchorEntity)
        
    } catch let err as NSError {
        print(err.debugDescription)
    }
}

我点击屏幕底部但激光发射并从屏幕顶部消失的屏幕截图。

在此处输入图像描述

标签: iosswiftarkittouch-event

解决方案


推荐阅读