我试图在一个平面上有5个球的世界中模拟重力。我遇到的第一个问题是球穿过地板是否有动态的身体。但如果我使用运动体,它们不会受到力的影响。所以我不得不使用动态体,禁用重力并使用重力场代替。场景是从COLLADA文件加载的。这就是我设置的方式:
self.scene = SCNScene(named: "art.scnassets/Balls.dae")!
for i in 1...5 {
let sphere = scene.rootNode.childNode(withName: "Sphere\(i)", recursively: true)!
let shape = SCNPhysicsShape(geometry: sphere.geometry!, options: nil)
let body = SCNPhysicsBody(type: .dynamic, shape: shape)
body.mass = 0.2
body.isAffectedByGravity = false
body.categoryBitMask = BallCategory
body.collisionBitMask = PlaneCategory | BallCategory | GravityFieldCategory
sphere.physicsBody = body
balls.append(sphere)
}
self.plane = self.scene.rootNode.childNode(withName: "Plane", recursively: true)
let shape = SCNPhysicsShape(geometry: self.plane.geometry!, options: nil)
let body = SCNPhysicsBody(type: .static, shape: shape)
body.categoryBitMask = PlaneCategory
body.collisionBitMask = BallCategory
self.plane.physicsBody = body
// Create a gravity field
let gravityField = SCNPhysicsField.linearGravity()
gravityField.categoryBitMask = GravityFieldCategory
gravityField.direction = SCNVector3Make(0.0, -1.0, 0.0)
gravityField.isActive = true
gravityField.strength = 3.0
let gravityNode = SCNNode()
gravityNode.physicsField = gravityField
self.scene.rootNode.addChildNode(gravityNode)
然后,当用户触摸屏幕时,随机球向上移动并且应该下降:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let index = Int(arc4random_uniform(5))
let ball = self.ball(atIndex: index)
let moveUp = SCNAction.move(by: SCNVector3Make(0.0, 2.0, 0.0), duration: 1.5)
ball.runAction(moveUp)
}
但不是摔倒而是停在那里,漂浮在真空中。重力场不起作用。这就是:https://youtu.be/egMe4lgPZY0
答案 0 :(得分:0)
似乎飞机的形状不正确。我试图通过传递nil作为形状参数来创建飞机的物理体:
self.plane = self.scene.rootNode.childNode(withName: "Plane", recursively: true)
let shape = SCNPhysicsShape(geometry: self.plane.geometry!, options: nil)
let body = SCNPhysicsBody(type: .static, shape: nil)
body.categoryBitMask = PlaneCategory
body.collisionBitMask = BallCategory
self.plane.physicsBody = body
我移除了重力场并打开了球的 isAffectedbyGravity 属性。它现在有效。