はじめに
こちらを参考にARKitで3Dモデルを表示しようとしたところ、「 Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value」のエラーが出たので、その対処を備忘録として。
実行環境
- Xcode 11.2.1
- MagicaVoxel 0.99.4
- Mixamo
コード
上記リンクのサンプルはボタンで使うscnを切り替えていたのですが、簡単にテストするために変数を「swing」固定としました。また SceneKit Catalog の名前も変更(art.scnassets)してあります。
var selectedItem: String? = "swing"
//(中略)
let scene = SCNScene(named: "art.scnassets/\(selectedItem).scn")
エラーになった箇所
以下のfunctionの childNode(withName:recursively:) で 「 Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value」のエラーが出ました。
func addItem(hitTestResult: ARHitTestResult) {
if let selectedItem = self.selectedItem {
// アセットのより、シーンを作成
let scene = SCNScene(named: "art.scnassets/\(selectedItem).scn")
// ノード作成
let node = (scene?.rootNode.childNode(withName: selectedItem, recursively: false))!
// 現実世界の座標を取得
let transform = hitTestResult.worldTransform
let thirdColumn = transform.columns.3
// アイテムの配置
node.position = SCNVector3(thirdColumn.x, thirdColumn.y, thirdColumn.z)
self.mainSceneView.scene.rootNode.addChildNode(node)
}
}
原因
SCNScene.childNode(withName:recursively:) は、SCNScene から withNname で指定した名前のノードを取得するメソッドですが、swing.scnに "swing" というノードが存在しないためでした。
対処
swing.scnを開いて、Scene graphパネルの左下の「+」ボタンでノードを追加して「swing」に名前を変更して、元々あったノードを「swing」ノードの配下にドラッグして移動します。
3Dオブジェクトのサイズ調整
3Dオブジェクトのサイズが大きすぎたので、サイズ変更のコードを追加してあります。
node.scale = SCNVector3(0.05, 0.05, 0.05)
/// アイテム配置メソッド
func addItem(hitTestResult: ARHitTestResult) {
if let selectedItem = self.selectedItem {
// アセットのより、シーンを作成
let scene = SCNScene(named: "art.scnassets/\(selectedItem).scn")
// ノード作成
let node = (scene?.rootNode.childNode(withName: selectedItem, recursively: false))!
// 現実世界の座標を取得
let transform = hitTestResult.worldTransform
let thirdColumn = transform.columns.3
// アイテムの配置
node.position = SCNVector3(thirdColumn.x, thirdColumn.y, thirdColumn.z)
// アイテムのサイズを変更
node.scale = SCNVector3(0.05, 0.05, 0.05)
self.mainSceneView.scene.rootNode.addChildNode(node)
}
}
ちなみに MagicaVoxelで作ったときのサイズは、21 21 21 でした。
この辺の適正サイズや,sncファイルのscale値で変更した方がいいのかは、現時点ではちょっとわからず。。。
まとめ
前提の知識(3Dモデルとか)が乏しいのでいろいろ躓いています。他の3Dアプリで作ったモデルはちゃんとノード名がつくんですかね。。。
MagicaVoexlについてはこちらを参考にしました。やはり公開することを考えると、オリジナルのモデルが必要になるので、簡単でいいです。
MagicaVoexlにアニメーションをつけるのには、Maximoを使いました。こちらもモデルをアップロードしてアニメーション選ぶだけなので、これまた簡単です。こちらを参考にしました(モデルをMagicaVoexlで作る場合は、Blender部分はすっ飛ばして大丈夫です)。