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

3 に答える 3

8

(キーの繰り返しによる)パルスの動きを最小限に抑えるには、「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) を自分で管理し、フレームごとにカメラの位置を更新して、このターゲットにスムーズに移動することです。

于 2012-09-26T09:57:48.030 に答える
1

私はこれを実験してきました。これまでに見つけた最良の方法は、入力キーの状態を内部状態で記録し、keyDown: と keyUp: で変更し、NSTimer を実行してそれらを適用することです。タイマーは、実際に測定された発射間の時間差を使用して、カメラをどれだけ動かすかを決定します。そうすれば、不規則なタイミングがあまり影響を与えません (また、メソッドを呼び出して、移動速度の変更を心配することなく、いつでもカメラの位置を更新できます)。

ただし、これを正しく動作させるには多少の作業が必要です。keyDown: と keyUp: は、ゲーム入力に関して不快な動作をします。たとえば、キーの繰り返し。また、ビューがフォーカスを失った後、またはアプリがバックグラウンドに移行した後でも、トランジション全体でキーが押されたままになっていると、それらが起動する場合があります。克服できないわけではありませんが、迷惑です。

私がまだ行っていないのは、加速と減速を追加することです。これは、スムーズであるという認識を助けると思います. それ以外はかなりいい感じです。

于 2012-11-18T04:12:00.507 に答える