Macos SceneKit平滑相机运动

Macos SceneKit平滑相机运动,macos,cocoa,opengl,scenekit,Macos,Cocoa,Opengl,Scenekit,在SceneKit(OpenGL)中平滑相机移动的标准方法是什么? 手动更改x、y不够平滑,但使用CoreAnimation会创建“脉冲”运动。SceneKit上的文档似乎非常有限,因此任何示例都将不胜感激,我目前正在这样做: - (void)keyDown:(NSEvent *)theEvent { int key = [theEvent keyCode]; int x = cameraNode.position.x; int y = cameraNode.positi

在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];
}

为了尽量减少脉冲移动(由于按键重复),您可以使用“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),并在每一帧更新相机的位置,以顺利到达该目标。

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

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


我还没有做的是增加加速和减速,我认为这将有助于让人感觉它是平稳的。否则感觉很好。

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

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

尝试将速度更改为较小的值,同时检查SCNTransaction的
动画计时功能
。确保
CAMediaTimingFunction
的函数名为kCAMediaTimingFunctionLinear,因此不会出现脉冲。我采取了类似的方法-除了我没有使用计时器-我只是更新了更新代理中的相机位置,它在大多数情况下工作得非常平稳-但是当FPS下降时,使用时移动并不平稳金属作为渲染器-当使用OpenGL作为渲染器时,它总是平滑的-但是FPS在OpenGL上下降的频率更高。。。