【问题标题】:SceneKit won't scale a dynamic bodySceneKit 不会缩放动态主体
【发布时间】:2015-03-09 16:38:51
【问题描述】:

我有一个球体,它是一个动态物体。我想为这个球体的比例设置动画,使其尺寸变大:

let sphere = SCNNode(geometry: SCNSphere(radius: 1))
scene.rootNode.addChildNode(sphere)
sphere.physicsBody = SCNPhysicsBody.dynamicBody()
sphere.runAction(SCNAction.scaleTo(10, duration: 1))

但是,这似乎不起作用。球体由于重力而下落,但尺寸保持不变。如果我注释掉赋予球体物理主体的线,那么缩放动画就会正常播放。

即使没有动画也能观察到这种奇怪的现象。简单地直接改变球体的比例是行不通的:

let sphere = SCNNode(geometry: SCNSphere(radius: 1))
scene.rootNode.addChildNode(sphere)
sphere.physicsBody = SCNPhysicsBody.dynamicBody()
sphere.scale = SCNVector3(x: 10, y: 10, z: 10)

球体下降,但半径仍为 1。除非球体在添加其物理体之前进行缩放。在这种情况下,球体开始缩放为 10 并下降,保持其半径为 10。

有趣的是,在动画运行后通过打印球体的比例进一步检查后,可以观察到比例确实发生了变化,除非物理体被移除,否则它是不可见的:

let sphere = SCNNode(geometry: SCNSphere(radius: 1))
scene.rootNode.addChildNode(sphere)
sphere.physicsBody = SCNPhysicsBody.dynamicBody()
sphere.runAction(SCNAction.scaleTo(10, duration: 1), completionHandler: {() in
    println(sphere.scale.x)
    sphere.physicsBody = nil
})

为什么不能改变动态体的尺度? (请注意,静态和运动的物体可以很好地缩放。)是否有可能以某种方式实现这一点?

【问题讨论】:

  • 物理引擎通常不支持在运行时缩放物体。唯一的解决方法是删除形状或主体并创建一个具有新尺寸的新形状或主体。你很快就会明白为什么物理引擎不能自己这样做,它是一罐蠕虫。
  • 我明白了。这就是我开始的想法,它不受支持似乎很奇怪。我想知道为什么会这样。
  • 一方面,它会在引擎的物理碰撞检测/解决阶段之外引入额外碰撞的可能性。即一个对象可能突然完全包含在另一个对象中。另外,如果一个对象增加比例,则必须有一个“缩放速度”,以便受增加比例影响的对象可以相应地被推开。这可能只是冰山一角,实际推理请联系物理引擎作者。 ;)
  • 嗯,是的,我想这是有道理的。

标签: swift ios8 scenekit


【解决方案1】:

当一个对象改变大小时,您不仅需要“缩放速度”来与其他对象交互,还需要“缩放力”。它应该在多大程度上推动它在成长过程中与之发生碰撞的事物?如果它处于依赖于它的质量的情况下会发生什么,比如在跷跷板上保持平衡?

游戏引擎已经是现实世界物理的松散近似,所以让他们自己弄清楚 Ant-Man 物理有点牵强。如果他们能做到这一点,他们可能也可以开始制造杀手机器人,那会毁了你的一天。 :)

无论如何,根据您希望您的扩展球体如何影响事物,您有几个选择。一种是每隔一段时间删除和重新创建物理体:

let duration = 5.0
node.runAction(.customActionWithDuration(duration, actionBlock: { node, progress in
    let scale = 1.0 + progress / CGFloat(duration)
    node.physicsBody = nil
    node.scale = SCNVector3(x: scale, y: scale, z: scale)
    node.physicsBody = .dynamicBody()
}))

每帧都会这样做,这可能会很昂贵——你可能想在那里对progress 设置一些门控,这样它就不会那么频繁地发生了。 (根据球体大小变化需要发生的其他效果,您可以在重新创建物理体时设置质量等内容。)

另一种选择可能是查看SCNPhysicsField。使用径向重力场创建一个区域,将所有内容推到其影响区域之外,然后为其参数设置动画以随时间改变大小和强度。

【讨论】:

    【解决方案2】:

    我在尝试缩放从 .scn 文件导入的模型时遇到了这个问题。就像 rickster 一样,我最终移除了物理体,缩放了形状,然后重新连接了物理体。这仅在启动期间完成,因此不会对性能产生很大影响。

    【讨论】:

      【解决方案3】:

      物理模拟是一种添加隐式/显式动画或动作的动画。因此,当将可动画属性更改为受影响的节点物理时,请特别考虑节点的动画状态。

      另一方面,sceneKit 将物理模拟结果应用于presentationNode,表示节点当前的渲染状态。你可以查看presentationNode的信息来确认你的动画为什么很烂。

      【讨论】:

        猜你喜欢
        • 2014-09-18
        • 2011-01-03
        • 1970-01-01
        • 2018-09-12
        • 2015-12-23
        • 2016-03-25
        • 2018-03-11
        • 2019-12-30
        • 2015-01-06
        相关资源
        最近更新 更多