我在 SceneKit 中遇到锥体和金字塔的物理问题,物理体似乎在地面上盘旋。如果我用一个 SCNBox 替换它,那么没有问题。它在较小的尺度上更明显,其中地面上的空间相对于节点的尺寸要大得多。这几乎就像有一个固定的偏移量。无论锥体是否具有面向地板的平坦侧面或点,都会发生这种情况。

下面的代码和屏幕截图(链接),示例创建并在新创建的 Xcode SceneKit 项目中运行。 (Xcode 9,swift 4 但在 Xcode 和 swift 3 的早期版本中也存在问题)。

几何图像 只是物理的图像

import UIKit
import QuartzCore
import SceneKit

var scnView: SCNView!

var scnScene: SCNScene!

var cameraNode: SCNNode!

let universalScale: Float = 1 / 40

enter image description hereclass GameViewController: UIViewController, SCNSceneRendererDelegate {
override func viewDidLoad() {
    super.viewDidLoad()

    setupView()
    setupScene()
    setupCamera()
    spawnFloor()
    spawnShape()
}

func setupView() {
    scnView = self.view as! SCNView
    scnView.showsStatistics = false
    scnView.allowsCameraControl = true
    scnView.autoenablesDefaultLighting = true
    scnView.debugOptions = .showPhysicsShapes
    scnView.showsStatistics = true
    scnView.delegate = self
}

func setupScene() {
    scnScene = SCNScene()
    scnView.scene = scnScene
}

func setupCamera() {
    cameraNode = SCNNode()
    cameraNode.camera = SCNCamera()
    cameraNode.position = SCNVector3(x: 0 * universalScale, y: 50 * universalScale, z: 50 * universalScale)
    cameraNode.rotation = SCNVector4Make(1, 0, 0, -Float(Double.pi)/4)
    scnScene.rootNode.addChildNode(cameraNode)
}

func spawnFloor() {
    let floor = SCNFloor()
    floor.reflectivity = 0.5
    let material = floor.firstMaterial
    material?.diffuse.contents = UIColor.gray
    let floorNode = SCNNode(geometry: floor)
    floorNode.physicsBody = SCNPhysicsBody(type: .static, shape: nil)
    scnScene.rootNode.addChildNode(floorNode)
}

var shapeNode: SCNNode?

func spawnShape(){
    let cone = SCNCone(topRadius: 0, bottomRadius:CGFloat(1 * universalScale), height: CGFloat(universalScale * 2))
    let coneShape = SCNPhysicsShape(geometry: cone, options: nil)
    let coneNode = SCNNode(geometry: cone)
    coneNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: coneShape)
    coneNode.position = SCNVector3(0, -coneNode.boundingBox.min.y + 20*universalScale, 0)
    scnScene.rootNode.addChildNode(coneNode)
    shapeNode = coneNode
}

func renderer(_ renderer: SCNSceneRenderer, didRenderScene scene: SCNScene, atTime time: TimeInterval) {
    if shapeNode != nil{
        print(shapeNode!.presentation.position)
        print(shapeNode!.boundingBox.min)
    }
}
}