【ARKit】配置した3Dモデル(アニメーションつき)を削除する
はじめに
別記事で書いたアニメーションつきの3DモデルをARKitに追加するのに引き続き、ARKItに追加した3Dモデル(アニメーションつき)を削除するときにも躓いたので、そのメモ。
以下のサイトを参考に、長押しで3Dモデルを消そうとしたが削除できませんでした。このサイトではプリミティブなオブジェクト(cube)を配置しているので、今回使う3Dモデル(アニメーションつき)と何が違うのか?
実行環境
- Xcode 11.2.1
3DモデルはMagicaVoxelで作って、Mixamo でアニメーションをつけたものを使用しました。
- MagicaVoxel 0.99.4
- Mixamo
.scnファイルの構造
.scnファイル(sitting.scn)を開いてみると、直下に「sitting」ノードがあって、その中に3Dモデルとボーンの設定が含まれています。
アニメーション付き3Dモデルの配置時
配置するスクリプトは、直下の「sitting」のノードを取得して、self.mainSceneView.scene.rootNode に追加するようになっていますが、追加するノードに名前がないため、名前をつける処理(node.name = selectedItem)を追加しました。
※削除する際に、どのノードか判断するためです。
var selectedItem: String? = "sitting"
//(中略)
/// アイテム配置メソッド
func addItem(hitTestResult: ARHitTestResult) {
if let selectedItem = self.selectedItem {
// .scnファイルから新しい3Dモデルのノードを作成
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
// 3Dモデルの配置
node.position = SCNVector3(thirdColumn.x, thirdColumn.y, thirdColumn.z)
// 3Dモデルのサイズを変更
node.scale = SCNVector3(0.05, 0.05, 0.05)
// 3Dモデルに名前をつける
node.name = selectedItem
// シーンに追加
self.mainSceneView.scene.rootNode.addChildNode(node)
}
}
アニメーション付き3Dモデルの削除
.scnファイルの構造で見たように、配置したモデルは「sitting」というノード名で、その中に3Dモデル(unamed)とボーン(mixamorig_Hips)が含まれています。
長押しでのオブジェクトが存在するかどうかの判定は、ARSCNView.hitTest(_:types:)で行いますが、このときの検出対象は3Dモデル(unamed)になるため、ノード全体を削除するには親である「sitting」ノードを削除する必要があります。
削除の処理は以下のようになります。
// ロングプレスイベントハンドラの登録
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPressView))
self.mainSceneView.addGestureRecognizer(longPressGesture)
//(中略)
// 長押しでキャラクタを削除する
@objc func longPressView(sender: UILongPressGestureRecognizer) {
print("----長押し!")
if sender.state == .began {
let location = sender.location(in: self.mainSceneView)
let hitTest = self.mainSceneView.hitTest(location)
if let result = hitTest.first {
// 3Dアニメーションモデルは、複数パーツで構成されるため、親ノードの名前で判定・削除する
if result.node.parent!.name == selectedItem
{
result.node.parent!.removeFromParentNode();
}
}
}
}
まとめ
ノードを扱う際には、常に階層構造を意識しないとダメってことですね(わかってみれば当然ですが)。
他にもっといい方法があれば、教えてください。
Author And Source
この問題について(【ARKit】配置した3Dモデル(アニメーションつき)を削除する), 我々は、より多くの情報をここで見つけました https://qiita.com/c_geru/items/30234bf5b94768b72b0f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .