我想将给定的 scn:SCNNode
和 其当前表示节点的转换设置为新值。但是,我在设置演示节点时遇到了问题。我试过四种方法:
scn.position = newVal
scn.presentation.position = newVal
scn.presentation.transform
是 只读 -- 无法设置。 (顺便说一句,设置表示节点的转换编译没有错误,也许需要清理一些东西)scn.position = newVal
scn.physicsBody.resetTransform()
什么都不做 。文档说它“更新物理模拟中 body 的位置和方向以匹配 body 所连接的节点的位置和方向”。但它没有改变。不清楚为什么!
let pb = scn.physicsBody
scn.physicsBody = nil
scn.position = newVal
scn.physicsBody = pb
这会将表示转换设置为 newVal ( "yea!" ),但 Physics 不起作用 ( "boo!" )。也许不能重复使用物理体。
scn.position = newVal
scn.physicsBody = SCNPhysicsBody(type:.dynamic, shape:nil)
但唉,scn.presentation.position 没有 newVal。
想法?
最佳答案
我在使用 SceneKit 的项目中也注意到了这一点。您的问题的直接答案是:“表示节点自动更新其变换以匹配场景节点的变换。如果它似乎没有更新,请确保场景节点的 isPaused
设置为 false
。”但是,很可能您的场景节点未暂停和/或您根本没有使用动画,但仍会出现此问题。
当我的项目中的所有内容在 iOS 10 上运行良好时,我开始注意到这个问题在 iOS 11 上间歇性发生。我没有接触 SCNAnimation
或类似的东西——我有自己的动画系统,所以我只是更新我节点的 .position
每个 renderer(_:, updateAtTime:)
.
所以 AFAICT,这里的问题不是你在做什么——问题是 SceneKit 一直有问题而且写得不好(API 的某些部分仍未针对 Swift 完全更新),并且可能仍然有问题写得不好是因为 SceneKit 团队似乎已经完全转向了 ARKit 的工作。因此,您的问题的解决方案似乎是“只是尝试一堆东西,比必要更频繁地设置 .position
,或者在更新循环中的不同时间,或者似乎解决 SceneKit 中的问题的真正黑客解决方案”。
就我个人而言,我正在慢慢地在我的项目中放弃 SceneKit——我主要切换到自定义 Metal 着色器,然后我将进行自己的场景渲染循环,最终我将替换场景图和 SCNNode
使用让我零依赖 SceneKit 的错误困惑。
我希望我有更好的消息告诉你,但我已经处理 SceneKit 的奇怪问题 2 年了。这是未完成的垃圾。
更新: 我最终“修复”了我的演示节点的行为不端,通过使用一个肮脏的黑客,在每一帧的节点位置上添加少量的“摆动”:
public func updateNode()
{
let wigglePositionValue = SCNVector3(
x: Float.random(in: -0.00001...0.0001),
y: Float.random(in: -0.00001...0.0001),
z: Float.random(in: -0.00001...0.0001)
)
self.scnNode.position = _locationModel.value + wigglePositionValue
}
旁注:正如预期的那样,像这样“摇晃”节点位置也不允许 SceneKit 进行一些批处理/渲染优化,并且(根据我的经验)会导致性能下降。这是一个可怕的变通方法,仅适用于最坏的情况(“客户说我们这周必须上线游戏,否则我们不会得到报酬,现在这个愚蠢的 SceneKit 错误?!”)
所以是的......这里真正的解决方案是“不要使用SceneKit”。
关于swift - 设置scnnode呈现位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51456876/