SceneKit不会缩放动态体

时间:2015-01-11 22:58:27

标签: swift ios8 scenekit

我有一个动态的球体。我想动画这个球体的比例,使它的大小增大:

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
})

为什么不能改变动态体的规模? (请注意,静态和运动体可以很好地扩展。)是否有可能以某种方式实现这一目标?

3 个答案:

答案 0 :(得分:7)

当你改变大小时,你不仅需要一个“缩放速度”来与其他对象进行交互,你需要一个“缩放力”。在成长过程中,它应该有多强烈地推动它碰撞的东西?如果它处于一种取决于其质量的情况,如跷跷板上的平衡,会发生什么?

游戏引擎已经是现实世界物理学的松散近似,所以要求他们自己找出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。使用径向重力场来制作一个区域,将所有东西推出其影响区域,然后设置其参数的动画以随时间改变大小和强度。

答案 1 :(得分:1)

当我尝试扩展从.scn文件导入的模型时遇到了这个问题。就像里克斯特那样,我最终移除了物理体,缩放了形状和尺寸。然后重新附上物理机构。这只是在启动期间完成的,因此不会产生很大的性能影响。

答案 2 :(得分:0)

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

另一方面,

,sceneKit将物理模拟的结果应用于presentationNodepresentationNode表示节点的当前渲染状态。您可以查看BotConversation = await Client.Conversations .StartConversationAsync().ConfigureAwait(false);的信息,以确认动画糟糕的原因。