iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
Mobile Development

iOS 菜雞的開發日記系列 第 27

鐵人賽 [Day 27] ARKit 教學(2)

  • 分享至 

  • xImage
  •  

今天要教大家怎麼跟 AR 的 3D 元件進行互動

移除 Box 元件的互動功能

在這邊,我們新增了手勢辨識在 ARSCNView,以便讓我們可以點擊螢幕和 AR 的 3D 元件進行互動

請新增“手勢會觸發其他 func 的變數“在 addBox

// 設定手勢辨識會觸發其他 func 的變數
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didTap))
// 新增手勢到 ARSCNView
vARSCNView.addGestureRecognizer(tapGestureRecognizer)

設定手勢點擊的功能 func(移除白色立方體)

@objc func didTap(recognizer: UIGestureRecognizer) {
    // 取得點擊位置
    let tapLocation = recognizer.location(in: vARSCNView)
    // 將點擊的位置放進點擊測試變數
    let hitTestResults = vARSCNView.hitTest(tapLocation)
    //判斷點擊測試是否有點到 node(白色 Box)
    guard let node = hitTestResults.first?.node else { return }
    // 有的話就移除
    node.removeFromParentNode()
}

結果看起來會是這樣子的:

請在 APP 中測試看看是否點擊到白色立方體會進行移除

新增點擊其他位置會新增白色立方體

我們先在 ViewController 新增 extension
為什麼要先新增這個 extension ,等等會進行說明
extension float4x4 {
    var translation: float3 {
        let translation = self.columns.3
        return float3(translation.x, translation.y, translation.z)
    }
}

修改 addBox() 的 Code

我們要判斷點擊的座標在哪,然後去進行新增物件
func addBox(x: Float = 0, y: Float = 0, z: Float = -0.2) {
    // Float 1 = 1公尺,產生一個 寬:0.1、高:0.1、長:0.1 的
    let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)

    // 新增一個叫 boxNode 的節點,代表位置與一物件在3D空間的座標
    let boxNode = SCNNode()
    boxNode.geometry = box
        
    // 座標設定,這個位置和相機有關係,以正x軸:右邊、負x軸:左邊、正Y軸:上方、負Y軸:下方、正Z軸:往後、負Z軸:往前
    boxNode.position = SCNVector3(x, y, z)
        
    let scene = SCNScene()
    scene.rootNode.addChildNode(boxNode)
    vARSCNView.scene = scene
        
    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didTap))
    vARSCNView.addGestureRecognizer(tapGestureRecognizer)
}

點擊事件修改

@objc func didTap(withGestureRecognizer recognizer: UIGestureRecognizer) {
    let tapLocation = recognizer.location(in: vARSCNView)
    let hitTestResults = vARSCNView.hitTest(tapLocation)
    guard let node = hitTestResults.first?.node else {
    
        // types參數要求hit test經由 AR 的相機圖像來搜尋真實世界的實體物或是表面。它內含許多類型,但本教學目前只針對特徵點
        let hitTestResultsWithFeaturePoints = vARSCNView.hitTest(tapLocation, types: .featurePoint)
        
        // 第一次hit test能成功移除,然後我們就將轉換矩陣類型 matrix_float4x4 到 float3 ,因為我們之前已增加了一個 extension 來完成此功能
        if let hitTestResultWithFeaturePoints = hitTestResultsWithFeaturePoints.first {
            let translation = hitTestResultWithFeaturePoints.worldTransform.translation
            
            在一特徵點上輸入x, y和z來加入一個立方體
            addBox(x: translation.x, y: translation.y, z: translation.z)
        }
        return
    }
    node.removeFromParentNode()
}

到此,大家可以測試看看是否有成功運行喔!!今天的教學就到這邊,今天學的只是 ARKit 的皮毛,還有東西可以進行學習!!


上一篇
鐵人賽 [Day 26] ARKit 教學
下一篇
鐵人賽 [Day 28] ARKit 教學(3)
系列文
iOS 菜雞的開發日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言