SceneKit平滑相机移动

6

在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,以避免脉冲。 - TheAmateurProgrammer
4个回答

8
为了减少由于按键重复而引起的脉冲运动,您可以使用“easeOut” timingFunction:
//move the camera
[SCNTransaction begin];
[SCNTransaction setAnimationDuration: 1.0];
[SCNTransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
// Change properties
cameraNode.position = SCNVector3Make(x, y, z);
[SCNTransaction commit];

话虽如此,在这里最好的做法可能是自己管理一个目标位置(一个vector3),并在每一帧更新摄像机的位置以平滑地移动到该目标。


1
我一直在尝试这个。到目前为止,我发现最好的方法是记录内部状态中输入键的状态,通过keyDown:和keyUp:进行修改,并运行NSTimer来应用它们。计时器使用实际测量的时间差来确定移动相机的距离。这样不规则的时间不会产生太大的影响(而且我可以随时调用我的方法来更新相机位置,而不必担心改变其移动速度)。
但是,要使其正确运行需要付出一些努力。当涉及到游戏输入时,keyDown:和keyUp:有一些讨厌的行为。例如,重复按键。此外,如果在过渡期间按住键,则即使视图失去焦点或应用程序进入后台,它们也可能触发。等等。虽然不是无法克服,但确实很烦人。
我还没有添加加速度和减速度,我认为这将有助于感知其平稳性。否则,它感觉相当不错。

我采用了类似的方法 - 除了我没有使用计时器 - 我只是在更新委托中更新了相机位置,它在大多数情况下运行得非常顺畅 - 但是当FPS下降时,使用Metal作为渲染器时移动不够平滑 - 当使用OpenGL作为渲染器时始终很平滑 - 但是在OpenGL上FPS更频繁地下降... - Coldsteel48

0
在我的方法中,我简单地将新位置(凸轮应该在哪里)与当前位置按一定比例“混合”。 CamPos.x = 0.1xNewPos + 0.9xCurrPos
根据比例,可以微调相机运动的平滑度。

0

我使用以下代码移动相机:

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

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