添加physicsBody使ar对象消失

问题描述

我正在尝试将简单的 3D 对象添加到 SceneView。向视图中添加对象相当简单,而且进展顺利。但是,当我尝试为碰撞目的添加主体时(BoxNode.physicsBody = BoxBody),立方体完全消失了,我再也找不到立方体了。

我错过了什么吗?我在下面附上了我的代码。项目的其余部分由项目设置选择“AR app”生成

import UIKit
import SceneKit
import ARKit

class ViewController: UIViewController,ARSCNViewDelegate,ARCoachingOverlayViewDelegate {

    @IBOutlet var sceneView: ARSCNView!
    
    let coachingOverlay = ARCoachingOverlayView()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Set the view's delegate
        sceneView.delegate = self
        
        // Show statistics such as fps and timing @R_977_4045@ion
        sceneView.showsstatistics = true
        
        
        let Box = SCNBox(width: 0.05,height: 0.05,length: 0.05,chamferRadius: 0)
        let BoxNode = SCNNode(geometry: Box)
        let BoxBody = SCNPhysicsBody(type: .dynamic,shape: nil)

        Box.firstMaterial?.diffuse.contents = UIColor.red
        BoxNode.position = SCNVector3(0.1,0)
//        BoxBody.mass = 1
////        BoxBody.categoryBitMask = CollisionBitmask.Box.rawValue
        BoxNode.physicsBody = BoxBody
//        BoxNode.rotation = SCNVector4Make(1,1,1)
//        BoxNode.name = "Box"
        sceneView.scene.rootNode.addChildNode(BoxNode)
        let scene = SCNScene()
        sceneView.scene = scene
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // Create a session configuration
        let configuration = ARWorldTrackingConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
    }
    
    override func viewWilldisappear(_ animated: Bool) {
        super.viewWilldisappear(animated)
        
        // Pause the view's session
        sceneView.session.pause()
    }

    // MARK: - ARSCNViewDelegate
    
/*
    // Override to create and configure nodes for anchors added to the view's session.
    func renderer(_ renderer: SCNSceneRenderer,nodeFor anchor: aranchor) -> SCNNode? {
        let node = SCNNode()
     
        return node
    }
*/
    
    func session(_ session: ARSession,didFailWithError error: Error) {
        // Present an error message to the user
        
    }
    
    func sessionWasInterrupted(_ session: ARSession) {
        // Inform the user that the session has been interrupted,for example,by presenting an overlay
        
    }
    
    func sessionInterruptionEnded(_ session: ARSession) {
        // Reset tracking and/or remove existing anchors if consistent tracking is required
        
    }
    
}

解决方法

使用 isAffectedByGravity 实例属性摆脱对象的重力:

var isAffectedByGravity: Bool { get set }

您需要 false 值(默认为 true):

let sphere = SCNSphere(radius: 1)
let node = SCNNode(geometry: sphere)
let physicsBody = SCNPhysicsBody(type: .dynamic,shape: nil)

node.physicsBody = physicsBody
physicsBody.isAffectedByGravity = false
sceneView.scene.rootNode.addChildNode(node)
,

您的对象可能会无限期地坠落,除非有一个 SCNFloor 或它下面的某个具有运动学模式的东西。

尝试添加一些东西来记录您的 SCNNode 的位置,轻按一下或每秒一次,您就会看到它在那一刻的位置;它可能有一个非常负的 y 坐标。