【问题标题】:SceneKit smooth camera movementSceneKit 平滑相机移动
【发布时间】:2012-09-17 13:42:41
【问题描述】:

在 SceneKit (OpenGL) 中平滑相机移动的标准方法是什么? 手动更改 x,y 不够平滑,但使用 CoreAnimation 会创建“脉冲”运动。 SceneKit 上的文档似乎非常有限,因此任何示例都将不胜感激,我目前正在这样做:

- (void)keyDown:(NSEvent *)theEvent {
    int key = [theEvent keyCode];
    int x = cameraNode.position.x;
    int y = cameraNode.position.y;
    int z = cameraNode.position.z;
    int speed = 4;
    if (key==123) {//left
        x-=speed;
    } else if (key==124) {//right
        x+=speed;
    } else if (key==125) {//down
        y-=speed;
    } else if (key==126) {//up
        y+=speed;
    }
    //move the camera
    [SCNTransaction begin];
    [SCNTransaction setAnimationDuration: 1.0];
    // Change properties
    cameraNode.position = SCNVector3Make(x, y, z);
    [SCNTransaction commit];
}

【问题讨论】:

  • 尝试将速度更改为较小的值,并检查 SCNTransaction 的animationTimingFunction。确保CAMediaTimingFunction 的函数名称是 kCAMediaTimingFunctionLinear,这样它就不会出现脉冲。

标签: macos cocoa opengl scenekit


【解决方案1】:

为了最大限度地减少脉冲运动(由于键重复),您可以使用“easeOut”计时函数:

//move the camera
[SCNTransaction begin];
[SCNTransaction setAnimationDuration: 1.0];
[SCNTransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
// Change properties
cameraNode.position = SCNVector3Make(x, y, z);
[SCNTransaction commit];

也就是说,这里最好的做法可能是自己管理一个目标位置(向量3),并在每一帧更新相机的位置以顺利到达该目标。

【讨论】:

    【解决方案2】:

    我一直在尝试这个。到目前为止,我发现的最好的方法是将输入键的状态记录为内部状态,由 keyDown: 和 keyUp: 修改,然后运行 ​​NSTimer 来应用它们。计时器使用触发之间实际测量的时间增量来确定移动相机的距离。这样不规则的计时不会有太大的影响(我可以随时调用我的方法来更新相机位置,而不必担心改变它的移动速度)。

    不过,要使其正常运行还需要一些工作。 keyDown: 和 keyUp: 在游戏输入方面有一些令人讨厌的行为。例如,重复键。此外,即使在您的视图失去焦点或您的应用程序进入后台后,如果在转换过程中按住键,它们也可能会触发。等等。不是不可克服,而是烦人。

    我还没有做的是添加加速和减速,我认为这将有助于感觉它是平滑的。否则感觉还不错。

    【讨论】:

    • 我做了类似的方法——除了我没有使用计时器——我只是在更新委托中更新了相机位置,它在大多数情况下工作得非常顺利——但是当 FPS 下降时,运动是使用 Metal 作为渲染器时不平滑 - 使用 OpenGL 作为渲染器时它总是平滑 - 但 OpenGL 上的 FPS 下降更频繁......
    【解决方案3】:

    我使用此代码移动相机:

    let lerpX = (heroNode.position.x - followCamera.position.x) * 0.05
    let lerpZ = (heroNode.position.z - followCamera.position.z) * 0.05
    followCamera.position.x += lerpX
    followCamera.position.z += lerpZ
    

    【讨论】:

      猜你喜欢
      • 2020-06-21
      • 1970-01-01
      • 2012-07-21
      • 2017-03-27
      • 2017-03-28
      • 2020-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多