将力施加到SceneKit物理实体?

时间:2018-01-11 08:10:49

标签: swift scenekit game-physics

我需要一些帮助来理解力如何应用于SceneKit中的物理实体。

我的SCNSphere定义如下:

    let startsphere = SCNSphere(radius: CGFloat(0.2))
    startsphere.firstMaterial?.diffuse.contents = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.3)
    let startsphereNode = SCNNode(geometry: startsphere)
    startsphereNode.position = SCNVector3(0.0, 1.0, 0.0) // center of playfield, 1m height
    startsphereNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)
    startsphereNode.physicsBody?.isAffectedByGravity = false
    startsphereNode.physicsBody?.friction = 0.0
    startsphereNode.physicsBody?.rollingFriction = 0.0
    startsphereNode.physicsBody?.damping = 0.0
    startsphereNode.physicsBody?.restitution = 1.0

这个球体被封装在一个由6个平面组成的盒子中,球体将从中弹回。碰撞掩模并设置为使球体从这些墙壁反弹,我可以观察到当我用SCNAction移动球体时。

现在我申请这样的力量:

  startsphereNode.physicsBody?.applyForce(SCNVector3(50000,0,0), at: startsphereNode.position, asImpulse: false)
  // or like this
  startsphereNode.physicsBody?.velocity = SCNVector3(200,0,0)

我观察场景中球体的行为。当施加力(或设定速度)时,球体瞬间在箱子外面向右跳跃,然后慢慢向后移动(向左方向)到其先前设定的位置(0,1,0)。我可以看到它穿过墙壁。

现在我的问题:

  1. 为什么它向右跳(而不是向右移动)?我已经玩过冲动和速度大小,但总是一样。

  2. 一旦施加了力量,它为什么会回到原来的位置?

  3. 为什么它不会从右墙反弹?我看到它"拍摄"墙。

  4. 我想要实现的行为是在施加力之后,根据物理设置,球体在我的盒子内弹跳。

    有什么想法?感谢。

2 个答案:

答案 0 :(得分:1)

以防这可能对其他人有所帮助:

问题是我的球体也有一个活动的SCNAction旋转。目前我删除了它开始按预期工作的所有SCNActions。

结果:不要同时使用SCNActions和物理模拟!

此致 克里斯

答案 1 :(得分:0)

快速回答你的问题......

  

为什么它向右跳(而不是向右移动)?我玩过了   脉冲和速度的大小,但总是一样的。

你可能没有使用计时器。如果你把动作放在计时器中并按住按钮或操纵杆等......你可以在一个有计时器持续时间的循环中移动它们。

@objc func rapidMove(_ timer: Timer) {
       self.sceneView.box.runAction(SCNAction.move(by: SCNVector3(-0.1,0,0), duration: 0.001))

    }
  

为什么一旦力量恢复到它的原始位置   申请?

您可能没有使用演示节点来更新位置。

Presentation Node - developer site

  

为什么它不会从右墙反弹?我看到它"拍摄"   墙。

您必须设置碰撞。

需要设置至少两个碰撞类别

 struct CollisionCategory: OptionSet {
let rawValue: Int

static let sphere  = CollisionCategory(rawValue: 1 << 0) // 00...01
static let box = CollisionCategory(rawValue: 1 << 1) // 00..10
  }



startsphereNode.physicsBody?.categoryBitmask = CollisionCategory.sphere.rawValue
startsphereNode.physicsBody?.contactTestBitMask = CollisionCategory.box.rawValue

您必须对您的盒子节点执行相同的操作,但反向

boxNode.physicsBody?.categoryBitmask = CollisionCategory.box.rawValue
boxNode.physicsBody?.contactTestBitMask = CollisionCategory.sphere.rawValue