【问题标题】:SceneKit physics is not behaving as intendedSceneKit 物理性能未按预期运行
【发布时间】:2017-10-25 00:42:39
【问题描述】:

我有 4 面墙、1 个天花板、1 个地板和一个家具。我在房间里拖着我的家具,但它正在穿过墙壁。我尝试了我所知道的一切。仍然无法解决问题。接触检测正在工作。如果我不给它 Furniture.physicsBody!.damping = 1.0 属性,我的家具节点就不会留在地板上。请查看视频:https://youtu.be/1iwq7gvTzA4

enum ABC:Int {
    case furni = 1
    case wall = 4
    case floor = 6
}

private func setup() {
    // create the wall geometry
    let wallGeometry = SCNPlane(width: 2000, height: 300)
    wallGeometry.firstMaterial!.diffuse.contents = "Wallpaper1.png"
    wallGeometry.firstMaterial!.isDoubleSided = false
    wallGeometry.firstMaterial!.locksAmbientWithDiffuse = true

    let wallWithBaseboardNode = SCNNode(geometry: wallGeometry)
    wallWithBaseboardNode.position = SCNVector3Make(0, 150, 0)
    wallWithBaseboardNode.physicsBody = .static()
    wallWithBaseboardNode.physicsBody!.restitution = 1.0
    wallWithBaseboardNode.physicsBody!.contactTestBitMask = ABC.furni.rawValue

    //front
    _wallNode = wallWithBaseboardNode.clone()
    _scene.rootNode.addChildNode(_wallNode)

    //left
    _wallNode = wallWithBaseboardNode.clone()
    _wallNode.position = SCNVector3Make(0, 150, 0)
    _wallNode.rotation = SCNVector4Make(0, 1, 0, .pi/2)
    _scene.rootNode.addChildNode(_wallNode)

    //right
    _wallNode = wallWithBaseboardNode.clone()
    _wallNode.position = SCNVector3Make(roomDimensions[0], 150, 0)
    _wallNode.rotation = SCNVector4Make(0, 1, 0, -.pi/2)
    _scene.rootNode.addChildNode(_wallNode)

    //back
    _wallNode = wallWithBaseboardNode.clone()
    _wallNode.position = SCNVector3Make(0, 150, roomDimensions[1])
    _wallNode.rotation = SCNVector4Make(0, 1, 0, .pi/1)
    _scene.rootNode.addChildNode(_wallNode)

    //ceiling
    var ceilingNode = wallWithBaseboardNode.clone()
    ceilingNode = wallWithBaseboardNode.copy() as! SCNNode
    ceilingNode.geometry = (ceilingNode.geometry!.copy() as! SCNGeometry)
    ceilingNode.geometry!.firstMaterial = SCNMaterial()
    ceilingNode.geometry!.firstMaterial!.diffuse.contents = UIColor.white
    ceilingNode.position = SCNVector3Make(0, Float(wallGeometry.height), 0)
    ceilingNode.scale = SCNVector3Make(10, 10, 10)
    ceilingNode.rotation = SCNVector4Make(1, 0, 0, .pi/2)
    _scene.rootNode.addChildNode(ceilingNode)

    //floor
    let floor = SCNFloor()
    floor.reflectionFalloffEnd = 0
    floor.reflectivity = 0

    _floorNode = SCNNode()
    _floorNode.geometry = floor
    _floorNode.geometry!.firstMaterial!.diffuse.contents = "Wood3.jpg"
    _floorNode.geometry!.firstMaterial!.locksAmbientWithDiffuse = true
    _floorNode.geometry!.firstMaterial!.diffuse.wrapS = .repeat
    _floorNode.geometry!.firstMaterial!.diffuse.wrapT = .repeat
    _floorNode.geometry!.firstMaterial!.diffuse.mipFilter = .nearest
    _floorNode.geometry!.firstMaterial!.isDoubleSided = false

    _floorNode.physicsBody = .static()
    _floorNode.physicsBody!.restitution = 1.0

    //_floorNode.physicsBody!.contactTestBitMask = ABC.furni.rawValue

    _scene.rootNode.addChildNode(_floorNode)
}

这是我的家具节点的代码

private func addFurniture() {
    let furnitureScene = SCNScene(named: "a.dae", inDirectory: "assets.scnassets/models/", options: nil)!
    let furniture = furnitureScene.rootNode.childNode(withName: "a", recursively: true)!

    furniture.physicsBody = .dynamic()
    furniture.physicsBody!.restitution = 1.0
    furniture.physicsBody!.damping = 1.0

    furniture.physicsBody!.contactTestBitMask = ABC.wall.rawValue

    _scene.rootNode.addChildNode(furniture)

    scnView.prepare(_scene, shouldAbortBlock: nil)

    _furniture = furniture

    scnView.debugOptions = [.showPhysicsShapes, .showPhysicsFields]
}

【问题讨论】:

  • 你知道contactTestBitMask和collisionBitMask的区别吗?如果这样做,将 contactTestBitMask 分配给您的节点的目的是什么?
  • @ElTomato 不,我不太确定。你能指导我解决这个问题吗?我是 SceneKit 的新手。我应该怎么做才能阻止这种情况发生。谢谢。
  • 不管怎样,为相关方设置affectedByGravity属性的物理体为false。
  • @ElTomato 你所说的“相关方”是什么意思?我已将affectedByGravity 设置为家具节点,但它并没有改变任何事情。已经好几天了。请帮我解决这个问题。谢谢。

标签: swift scenekit


【解决方案1】:

如果您想手动移动家具(即不使用力),请将主体类型更改为 .kinematic

当您移动节点时,您可以执行contactTest(with:options:),如果您撞墙,它将返回一个联系人列表。然后在renderer(_:willRenderScene:atTime:) 中,您可以固定家具的位置以“固定”墙壁穿透偏移对墙壁的影响。

您可以在此处查看我对类似问题的解决方案: https://stackoverflow.com/a/46915698/1389597

希望这会有所帮助,我已经花了几天的时间试图解决这个问题:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 2017-07-19
    • 2018-10-04
    • 1970-01-01
    • 2014-04-11
    相关资源
    最近更新 更多