iT邦幫忙

2025 iThome 鐵人賽

DAY 3
0
Mobile Development

使用 AR 魔杖呼喚屬於自己的魔法小卡!系列 第 3

Day 3 將魔杖展現出來(RealityView)

  • 分享至 

  • xImage
  •  

Day 2 時開啟了雙版本的 AR 畫面,不過還是先打通其中一邊比較合理(?)。
先從 RealityView 來吧!
今天先請 AI 畫一張 3D 木質魔杖的 png 圖片,看看在 AR 中產生一個平面中放上圖片的樣子。
https://ithelp.ithome.com.tw/upload/images/20250909/20162426jtgrF5TxUT.png
還蠻有質感的。

import SwiftUI
import RealityKit
import ARKit

@available(iOS 18.0, *)
struct RealityCameraView: View {
    
    var body: some View {
        RealityView { content in
            content.camera = .spatialTracking
            
            guard let uiImage = UIImage(named: "Wand.png"),
                  let texture = try? TextureResource.generate(from: uiImage.cgImage!, options: .init(semantic: .color)) else {
                return
            }

            let mesh = MeshResource.generatePlane(width: 0.04, height: 0.25)
            var material = SimpleMaterial()
            material.color = .init(texture: .init(texture))

            let entity = ModelEntity(mesh: mesh, materials: [material])
            entity.components.set(BillboardComponent())
            
            let anchor = AnchorEntity(.camera)
            entity.position = [0, 0, -0.4]
            anchor.addChild(entity)

            content.add(anchor)
        }

        .ignoresSafeArea()
    }
}

分段拆解:

            guard let uiImage = UIImage(named: "Wand.png"),
                  let texture = try? TextureResource.generate(from: uiImage.cgImage!, options: .init(semantic: .color)) else {
                return
            }

這裡是將已放入 Assets.xcassets 的圖片 Wand.png 載入,在 RealityKit 的領域中,都要轉換為 TextureResource。

            let mesh = MeshResource.generatePlane(width: 0.04, height: 0.25)

生成一片平面網格,注意這裡的單位是公尺。寬 4 公分、高 25 公分,當作魔杖的載體。

            var material = SimpleMaterial()
            material.color = .init(texture: .init(texture))

建立 SimpleMaterial,它會反應基本光照,並支援貼圖。
把上面的 texture 指定成顏色貼圖(Color)。

            let entity = ModelEntity(mesh: mesh, materials: [material])

建立一個 3D 實體(RealityKit 物件)。

            entity.components.set(BillboardComponent())

讓平面自動朝向相機。

            let anchor = AnchorEntity(.camera)
            entity.position = [0, 0, -0.4]
            anchor.addChild(entity)

建立一個相機錨點,會固定跟著相機座標移動。
把魔杖放在相機前 40 公分(Z 軸負方向是鏡頭前方),並將魔杖掛到錨點之下。
試過大於 -40 公分,魔杖會變更大隻,如果 Z 軸為 0 則看不見魔杖。如果小於 -40 公分則魔杖越來越短。

            content.add(anchor)

最後,把錨點(連同魔杖實體)加入 RealityView 的內容中。

目前鏡頭對著牆面的效果:
https://ithelp.ithome.com.tw/upload/images/20250909/20162426aYTDKO9DxN.png

另外,會發現如果太貼近牆面,魔杖會被吃掉:
https://ithelp.ithome.com.tw/upload/images/20250909/20162426iHoA4ctCfp.png

這是我將手機前傾,讓魔杖被吃掉一半的樣子。
position z 軸設定越小,則需要離牆面的距離越遠,才能讓魔杖出現。


下一回要找找看如何將魔杖自黑色平面中釋放。


上一篇
Day 2 SwiftUI 專案設定與 AR 起始畫面
系列文
使用 AR 魔杖呼喚屬於自己的魔法小卡!3
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言