2012-09-26 8 views
6

Jaka jest standardowa metoda płynnego ruchu kamery w programie SceneKit (OpenGL)? Ręczna zmiana x, y nie jest wystarczająco płynna, ale użycie CoreAnimation tworzy ruch "pulsujący". Docs na SceneKit wydają się być bardzo ograniczona, a więc wszelkie przykłady byłoby mile widziane, jestem obecnie to robi:SceneKit płynny ruch kamery

- (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

Spróbuj zmienić prędkość na mniejszą wartość, a także sprawdź "AnimationTimingFunction" SCNTransaction. Upewnij się, że nazwa funkcji 'CAMediaTimingFunction' jest kCAMediaTimingFunctionLinear, więc nie pulsuje. – TheAmateurProgrammer

Odpowiedz

1

Eksperymentowałem z tym. Najlepszym jak dotąd odkryłem jest zapisanie stanu kluczy wejściowych w stanie wewnętrznym, zmodyfikowanych przez keyDown: i keyUp :, i uruchomienie NSTimer'a, aby je zastosować. Timer wykorzystuje rzeczywistą, zmierzoną różnicę czasu pomiędzy wyzwaniami, aby określić, jak daleko przesunąć kamerę. W ten sposób nieregularne taktowanie nie ma zbyt dużego efektu (i mogę nazwać moją metodę aktualizacji położenia kamery w dowolnym momencie, nie martwiąc się o zmianę prędkości ruchu).

Trzeba jednak trochę pracy, aby zachować prawidłowe zachowanie. keyDown: and keyUp: miej trochę nieprzyjemnych zachowań, jeśli chodzi o wejście do gry. Na przykład powtarzanie kluczy. Mogą też strzelać nawet po utracie koncentracji widoku lub gdy Twoja aplikacja zostanie przeniesiona w tło, jeśli przytrzymasz klawisze w trakcie przejścia. Itd. Nie nieprzezwyciężony, ale denerwujący.

To, czego jeszcze nie zrobiłem, to przyspieszenie i spowolnienie, które, jak sądzę, ułatwi sprawdzenie płynności. W przeciwnym razie wydaje się całkiem nieźle.

+0

Zrobiłem w jakiś sposób podobne podejście - z wyjątkiem tego, że nie korzystałem z timera - właśnie zaktualizowałem pozycję kamery w obrębie delegata aktualizacji, który działa dość sprawnie w większości przypadków - jednak kiedy FPS spada, ruch nie jest płynny, gdy używa się metalu jako renderera - podczas korzystania z OpenGL jako renderer jest zawsze gładki - ale FPS częściej spada na OpenGL ... – ColdSteel

8

Aby zminimalizować ruchy pulsujące (ze względu na kluczową repeat) można użyć „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]; 

powiedział, że najlepszą rzeczą do zrobienia jest prawdopodobnie zarządzać pozycji docelowej (a) Vector3 siebie i aktualizowania położenia kamery w każdej klatce, aby przejść do tego celu gładko.