opengl SceneKit平滑的摄像机移动

mwkjh3gx  于 2023-03-02  发布在  其他
关注(0)|答案(4)|浏览(159)

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

t9eec4r01#

为了最大限度地减少脉冲运动(由于按键重复),您可以使用“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];

也就是说,这里要做的最好的事情可能是自己管理一个目标位置(vector3),并在每一帧更新相机的位置,以平滑地到达这个目标。

nkhmeac6

nkhmeac62#

我一直在做这样的实验,到目前为止,我发现最好的方法是在internal state中记录输入键的状态,并通过keyDown进行修改:和keyUp:,并运行一个NSTimer来应用它们。计时器使用实际测量的两次触发之间的时间增量来确定相机移动多远。这样,不规则的计时就不会有太大的影响(而且我可以随时调用我的方法来更新相机的位置,而不必担心改变它的移动速度)。
不过,要使其正确运行还需要一些工作。keyDown:和keyUp:在游戏输入方面有一些令人讨厌的行为。例如,重复按键。此外,如果在切换过程中按住按键,即使在视图失去焦点或应用程序转到后台后,它们也可能会触发。等等。并非无法克服,但很烦人。
我还没有做的是增加加速和减速,我认为这将有助于感觉它是平稳的。否则感觉相当不错。

wbrvyc0a

wbrvyc0a3#

我移动相机使用这个代码:

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
57hvy0tb

57hvy0tb4#

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

相关问题