Search code examples
swiftscenekit

SceneKit - How to Add Animations to Change SCNNode's Color?


I would like to know how I can animate an SCNNode's color using Swift.

For example: I would like the node to constantly be changing color or I would like the node to fade from black to blue.

Do I use the SCNAction fadeIn or fadeOut?


Solution

  • Got idea from @Luca Angeletti, I write the code so we can animate between any colors, include their alphas:

    func aniColor(from: UIColor, to: UIColor, percentage: CGFloat) -> UIColor {
        let fromComponents = from.cgColor.components!
        let toComponents = to.cgColor.components!
    
        let color = UIColor(red: fromComponents[0] + (toComponents[0] - fromComponents[0]) * percentage,
            green: fromComponents[1] + (toComponents[1] - fromComponents[1]) * percentage,
            blue: fromComponents[2] + (toComponents[2] - fromComponents[2]) * percentage,
            alpha: fromComponents[3] + (toComponents[3] - fromComponents[3]) * percentage)
        return color
    }
    

    Use:

    let oldColor = UIColor.red
    let newColor = UIColor(colorLiteralRed: 0.0, green: 0.0, blue: 1.0, alpha: 0.5)
    let duration: TimeInterval = 1
    let act0 = SCNAction.customAction(duration: duration, action: { (node, elapsedTime) in
        let percentage = elapsedTime / CGFloat(duration)
        node.geometry?.firstMaterial?.diffuse.contents = self.aniColor(from: newColor, to: oldColor, percentage: percentage)
    })
    let act1 = SCNAction.customAction(duration: duration, action: { (node, elapsedTime) in
        let percentage = elapsedTime / CGFloat(duration)
        node.geometry?.firstMaterial?.diffuse.contents = self.aniColor(from: oldColor, to: newColor, percentage: percentage)
    })
    
    let act = SCNAction.repeatForever(SCNAction.sequence([act0, act1]))
    node.runAction(act)