SceneKit不会缩放动态物体。

6
我有一个动态体的球体。我想要通过动画来改变这个球体的尺寸,让它变得更大:
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的半径。
有趣的是,在动画 supposedly 运行后打印出球体的比例进行进一步检查时,观察到比例确实发生了变化,只不过除非删除物理体,否则看不见:
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
})

为什么动态物体的比例无法更改?(请注意,静态和运动学物体可以轻松缩放。)有没有办法实现这一点?

2
物理引擎通常不支持在运行时缩放物体。唯一的解决方法是移除形状或物体,并创建一个新的具有新尺寸的物体。你很快就会明白为什么物理引擎不会自动这样做,因为这是一个棘手的问题。 - CodeSmile
我明白了。这正是我开始思考的,只是它不支持看起来很奇怪。不知道为什么会这样。 - David Bagwell
1
首先,这将引入可能在引擎的物理碰撞检测/解决阶段之外发生额外碰撞的可能性。例如,一个对象可能会突然完全包含在另一个对象内部。此外,如果一个对象增加了比例,就必须有一个“缩放速度”,以便受增加比例影响的对象可以相应地被推开。这可能只是冰山一角,有关实际原因,请联系物理引擎作者。;) - CodeSmile
嗯,是的,我想那很有道理。 - David Bagwell
3个回答

11

如果一个物体正在改变大小并与其他物体互动,你不仅需要一个“缩放速度”,还需要一个“缩放力”。它在增长时会对碰撞的物体施加多大的力?如果它处于依赖其质量的情况中,例如在平衡木上平衡,会发生什么?

游戏引擎已经是对真实世界物理的松散近似,所以要求它们自己解决蚁人物理问题有些牵强。如果它们可以做到这一点,它们可能也能开始制造杀人机器人,那会毁掉你的一天 :)

无论如何,根据您希望扩展球体影响事物的方式,您有几个选项。其中之一是定期删除和重新创建物理体:

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
我在尝试缩放从.scn文件导入的模型时遇到了这个问题。就像rickster所做的那样,我最终删除了物理体,缩放了形状,然后重新附加了物理体。这只是在启动期间完成的,因此对性能影响不大。

0

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

另一方面,SceneKit将物理模拟的结果应用于presentationNode,它代表节点的当前渲染状态。您可以检查presentationNode的信息以确认为什么您的动画效果不佳。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接