SceneKit流畅的相机运动

Cal*_*l S 6 opengl macos cocoa scenekit

在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];
}
Run Code Online (Sandbox Code Playgroud)

小智 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];
Run Code Online (Sandbox Code Playgroud)

也就是说,在这里做的最好的事情可能是自己管理一个目标位置(一个vector3)并在每一帧更新摄像机的位置以顺利地到达这个目标.


Wad*_*kis 1

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

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

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