iosswiftscenekitscnview

How to animate the background color of a scene view (SCNView). Note, not a scene (SCNScene), or conventional UIView


Is it possible to animate the .backgroundColor property of an SCNView?

Please note, it is easy to animate the background of an actual scene (SCNScene) and I know how to do that. It is also easy to animate the background of a conventional UIView.

I've not been able to figure out how to animate the .backgroundColor property of an SCNView.


Solution

  • Assuming you take the default SceneKit Game Template (the one with the rotating Jet) I got it working by doing this:

    Here is my viewDidLoad

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // create a new scene
        let scene = SCNScene() // SCNScene(named: "art.scnassets/ship.scn")!
        
        // create and add a camera to the scene
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        scene.rootNode.addChildNode(cameraNode)
        
        // place the camera
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
        
        // create and add a light to the scene
        let lightNode = SCNNode()
        lightNode.light = SCNLight()
        lightNode.light!.type = .omni
        lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
        scene.rootNode.addChildNode(lightNode)
        
        // create and add an ambient light to the scene
        let ambientLightNode = SCNNode()
        ambientLightNode.light = SCNLight()
        ambientLightNode.light!.type = .ambient
        ambientLightNode.light!.color = UIColor.darkGray
        scene.rootNode.addChildNode(ambientLightNode)
        
        // retrieve the ship node
        // let ship = scene.rootNode.childNode(withName: "ship", recursively: true)!
        
        // animate the 3d object
        // ship.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: 2, z: 0, duration: 1)))
        
        // retrieve the SCNView
        let scnView = self.view as! SCNView
        
        // set the scene to the view
        scnView.scene = scene
        
        // allows the user to manipulate the camera
        scnView.allowsCameraControl = true
        
        // show statistics such as fps and timing information
        scnView.showsStatistics = true
        
        // Configure the initial background color of the SCNView
        scnView.backgroundColor = UIColor.red
        
        // Setup a SCNAction that rotates i.Ex the HUE Value of the Background
        let animColor = SCNAction.customAction(duration: 10.0) { _ , timeElapsed in
            
            scnView.backgroundColor = UIColor.init(hue: timeElapsed/10, saturation: 1.0, brightness: 1.0, alpha: 1.0)
            
        }
    
        // Run the Action (here using the rootNode)
        scene.rootNode.runAction(animColor)
        
        // add a tap gesture recognizer
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
        scnView.addGestureRecognizer(tapGesture)
    }
    

    This might not be the best solution, but using a SCNTransaction I had no luck. Hope I could help in some way.