SceneKit 物理碰撞

前言

SceneKit使用SCNPhysicsWorld来管理这种物理模拟,让物体的碰撞、连接、掉落等具有真实感。
SCNPhysicsBody:想要一个SCNNode参与到物理模拟中,只需要给node.physicsBody赋值一个合适的值,SCNPhysicsBody有三种类型

  • dynamic: 动态的物体,受力的影响(applyForce)。
  • static: 静态的物体,不受力的影响,且不能移动。适合场景中地面、墙体等。
  • kinematic: 不受碰撞、力影响,在空间变换中,会对dynamic的物体产生力的影响。
实践
 override func viewDidLoad() {
        super.viewDidLoad() 
        let sceneView = SCNView(frame: view.bounds)
        sceneView.backgroundColor = UIColor.black
        sceneView.scene = SCNScene()
        sceneView.allowsCameraControl = true
        sceneView.showsStatistics = true
        //设置运动速度
        sceneView.scene?.physicsWorld.speed = 5
        view.addSubview(sceneView)
    
        //添加照相机
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(0, 10, 20)
        // 因为要显示地板 多以要倾斜一点角度(绕X轴旋转,绕哪个轴旋转哪个轴的值就为1)
        cameraNode.rotation = SCNVector4(1, 0, 0, -Double.pi * 0.1)
        cameraNode.camera?.automaticallyAdjustsZRange = true
        sceneView.scene?.rootNode.addChildNode(cameraNode)
        //添加地板
        let floorNode = SCNNode()
        let floor = SCNFloor()
        floor.firstMaterial?.diffuse.contents = "floor.jpg"
        floorNode.geometry = floor
        // 如果没有这一行代码,柱状物体会直接下沉到不见为止
        floorNode.physicsBody = SCNPhysicsBody.static()
        sceneView.scene?.rootNode.addChildNode(floorNode)
        
        // 添加动态事物
        for _ in 0..<10 {
            let box = SCNBox(width: 0.5, height: 3, length: 1, chamferRadius: 0)
            box.firstMaterial?.diffuse.contents = "1.PNG"
            let node = SCNNode(geometry: box)
            node.physicsBody = SCNPhysicsBody.dynamic()
            node.position = SCNVector3(Float(arc4random_uniform(5)) - 2, 1.5, Float(arc4random_uniform(5)))
            sceneView.scene?.rootNode.addChildNode(node)
        }
        // 继续添加动态事物
        for _ in 0..<5 {
            let node = SCNNode()
            let sphere = SCNSphere(radius: 1)
            sphere.firstMaterial?.diffuse.contents = "sun.jpg"
            node.geometry = sphere
            node.physicsBody = SCNPhysicsBody.dynamic()
            node.position = SCNVector3(Float(arc4random_uniform(5)) - 2, 10, Float(arc4random_uniform(5)))
            sceneView.scene?.rootNode.addChildNode(node)
        }
}
  • 效果图


    碰撞.gif
碰撞.gif

你可能感兴趣的:(SceneKit 物理碰撞)