1

I have an SCNCamera working in a 3D SceneKit view on iOS.

When I change orientation of the screen, in order to keep the world objects the same size and relative positions I need to change the FoV of the SCNCamera.

However, I can't animate this change, so instead the world 'flashes' or 'pulses' as the FoV is changed from one setting to another.

Is there a way of doing this smoothly so that the change in FoV isn't so abrupt that it causes the objects in the world to 'pulse'?

When the device changes orientation, this code is executed:

if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight
{
    self.cameraNode?.camera?.fieldOfView  = 38
}
else
{
    self.cameraNode?.camera?.fieldOfView  = 50
}

I've tried wrapping the FoV change in a UIView animation block but that didn't work.

I've tried to run it on it's on thread with a delay but that still caused the visual 'pulse' as the FoV changed.

Is there some way to make this transition smooth?

Elphaba
  • 89
  • 1
  • 9

1 Answers1

4

You need to add your code with SCNTransaction like as follow to do animation.

The SCNTransaction class defines SceneKit's architecture for scene content changes, including implicit animations: A transaction is a single atomic operation that combines multiple changes to nodes, geometries, materials, or other scene content.

    if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight {
    SCNTransaction.begin()
    SCNTransaction.animationDuration = 1.5
    self.cameraNode?.camera?.fieldOfView = 38
    SCNTransaction.commit()
} else {
    SCNTransaction.begin()
    SCNTransaction.animationDuration = 1.5
    self.cameraNode?.camera?.fieldOfView = 50
    SCNTransaction.commit()
}
Sagar Chauhan
  • 5,715
  • 2
  • 22
  • 56
  • Wow, so I can do that even on properties that Apple don't explicitly state as animatable? – Elphaba Sep 09 '19 at 09:34
  • 1
    Not sure, but Yes. – Sagar Chauhan Sep 09 '19 at 09:35
  • 1
    You can read more about `SCNTransaction` here: https://developer.apple.com/documentation/scenekit/animation/animating_scenekit_content – Sagar Chauhan Sep 09 '19 at 09:37
  • This is the new syntax: ```swift if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight { SCNTransaction.begin() SCNTransaction.animationDuration = 0.5 self.cameraNode?.camera?.fieldOfView = 38 SCNTransaction.commit() } else { SCNTransaction.begin() SCNTransaction.animationDuration = 0.5 self.cameraNode?.camera?.fieldOfView = 50 SCNTransaction.commit() } ``` – Elphaba Sep 09 '19 at 09:39
  • Is it possible to share your demo code? Means project file.? – Sagar Chauhan Sep 09 '19 at 09:40
  • 1
    This works brilliantly, but I had to up the duration to 1.5 and it smoothly transitions, shorter durations gave the same pulse / flash, but now it's fixed. Thanks @Sagar Chauhan! – Elphaba Sep 09 '19 at 09:42
  • 1
    @Elphaba, Pleasure to help you. – Sagar Chauhan Sep 09 '19 at 09:42
  • 1
    @Elphaba, Thanks for reply, I have updated animation duration. – Sagar Chauhan Sep 09 '19 at 09:43