我想将给定的 scn:SCNNode 其当前表示节点的转换设置为新值。但是,我在设置演示节点时遇到了问题。我试过四种方法:

  • 设置表示节点的变换:
    scn.position              = newVal
    scn.presentation.position = newVal
    
    scn.presentation.transform 只读 -- 无法设置。 (顺便说一句,设置表示节点的转换编译没有错误,也许需要清理一些东西)
  • 使用 resetTransform():
    scn.position              = newVal
    scn.physicsBody.resetTransform()
    

    什么都不做 。文档说它“更新物理模拟中 body 的位置和方向以匹配 body 所连接的节点的位置和方向”。但它没有改变。不清楚为什么!
  • 设置时移除physicsBody:
    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/

    10-14 22:05
    查看更多