2012-09-26 11 views
6

Was ist die Standardmethode für weiche Kamerabewegungen innerhalb von SceneKit (OpenGL)? Manuelles Ändern von x, y ist nicht glatt genug, doch die Verwendung von CoreAnimation erzeugt eine "pulsierende" Bewegung. Die docs auf SceneKit scheinen sehr begrenzt sein so dass alle Beispiele geschätzt würden, ich dies derzeit tun:SceneKit glatte Kamerabewegung

- (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]; 
} 
+0

Versuchen Sie, die Geschwindigkeit auf einen kleineren Wert zu ändern und überprüfen Sie auch die 'animationTimingFunction' von SCNTransaction. Stellen Sie sicher, dass der Funktionsname von CAMediaTimingFunction kCAMediaTimingFunctionLinear lautet und nicht pulsiert. – TheAmateurProgrammer

Antwort

1

Ich habe damit experimentiert. Das Beste, was ich bisher gefunden habe, ist, den Zustand der Eingabetasten im internen Zustand aufzuzeichnen, modifiziert durch keyDown: und keyUp:, und einen NSTimer auszuführen, um sie anzuwenden. Der Timer verwendet das tatsächliche, gemessene Zeitdelta zwischen den Abfeuerungen, um zu bestimmen, wie weit die Kamera bewegt werden soll. Auf diese Weise haben unregelmäßige Timings keine allzu große Wirkung (und ich kann meine Methode jederzeit dazu aufrufen, die Kameraposition zu aktualisieren, ohne sich Gedanken über die Änderung der Bewegungsgeschwindigkeit machen zu müssen).

Es bedarf jedoch einiger Arbeit, damit sich dies korrekt verhält. keyDown: und keyUp: haben einige anstößige Verhaltensweisen, wenn es um Spieleingaben geht. Zum Beispiel, Schlüssel zu wiederholen. Sie können auch ausgelöst werden, wenn die Anzeige den Fokus verliert oder die App in den Hintergrund wechselt, wenn die Tasten während des Übergangs gedrückt gehalten werden. Etc. Nicht unüberwindbar, aber nervig.

Was ich noch nicht getan habe, ist Beschleunigung und Verlangsamung hinzuzufügen, was meiner Meinung nach die Wahrnehmung erleichtern wird, dass es glatt ist. Sonst fühlt es sich ziemlich gut an.

+0

Ich habe irgendwie ähnliche Ansatz - außer ich habe keinen Timer - Ich habe nur aktualisiert die Kamera Position innerhalb der Update-Delegate funktioniert es ziemlich glatt in den meisten Zeiten - aber wenn der FPS fällt die Bewegung ist nicht glatt, wenn Metall als Renderer - Wenn OpenGL als Renderer verwendet wird, ist es immer flüssig - aber FPS fällt häufiger bei OpenGL ... – ColdSteel

8

die pulsierenden Bewegungen zu minimieren (aufgrund der Tastenwiederholung) Sie einen „easeOut“ timingFunction verwenden können :

//move the camera 
[SCNTransaction begin]; 
[SCNTransaction setAnimationDuration: 1.0]; 
[SCNTransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; 
// Change properties 
cameraNode.position = SCNVector3Make(x, y, z); 
[SCNTransaction commit]; 

das heißt, das beste, was hier zu tun ist wahrscheinlich eine Zielposition (a vector3) selbst und aktualisieren Sie die Position der Kamera in jedem Rahmen glatt an dieses Ziel zu gehen, zu verwalten.