Smooth SceneKit Camera Movement

What is the standard method for smoothly moving the camera inside SceneKit (OpenGL)? Changing x, y manually is not smooth enough, but using CoreAnimation creates a pulsating motion. The documents on SceneKit seem very limited, so any examples will be appreciated, I am currently doing this:

- (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]; } 
+6
source share
2 answers

I experimented with this. The best I have found so far is to record the state of the input keys in the internal state, modified by keyDown: and keyUp :, and run NSTimer to apply them. The timer uses the actual measured time delta between shots to determine how far to move the camera. Thus, irregular timings do not have too much effect (and I can call my method to update the camera position at any time, without worrying about changing the speed of its movement).

It takes some work to get it right. keyDown: and keyUp: there are some unpleasant behaviors when it comes to game input. For example, repeating keys. In addition, they can work even after your presentation loses focus, or your application goes to the background if the keys are held in transition. Etc. Not irresistible, but annoying.

What I have not done yet is to add acceleration and deceleration, which, I think, will help to perceive it smoothly. Otherwise, he feels rather well.

+1
source

To minimize ripple (due to key repetition), you can use the "easyOut" timingFunction function:

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

However, the best thing that can be done here is probably to independently control the target position (vector3) and update the camera position in each frame in order to smoothly transition to this goal.

+8
source

Source: https://habr.com/ru/post/926262/


All Articles