Reputation: 355
I want to make a node blinking (loop from input color to current firstMaterial for example). The node has a material which is shared with many others nodes but I don't want all the nodes blinking (only selected nodes).
I succeeded to do that without SCNAction/SCNTransaction but the code is dirty, very hard to maintain and must be called in Update()... I was wondering if SCNAction/SCNTransaction could help me but I don't know how to do this the right way.
Upvotes: 0
Views: 1197
Reputation: 7385
I believe something like this will point you in the right direction.
First we will create an extension
of SCNNode
so that we can make use of our function on any SCNNode
:
//-----------------------
//MARK: SCNNode Extension
//-----------------------
extension SCNNode{
/// Creates A Pulsing Animation On An Infinite Loop
///
/// - Parameter duration: TimeInterval
func highlightNodeWithDurarion(_ duration: TimeInterval){
//1. Create An SCNAction Which Emmits A Red Colour Over The Passed Duration Parameter
let highlightAction = SCNAction.customAction(duration: duration) { (node, elapsedTime) in
let color = UIColor(red: elapsedTime/CGFloat(duration), green: 0, blue: 0, alpha: 1)
let currentMaterial = self.geometry?.firstMaterial
currentMaterial?.emission.contents = color
}
//2. Create An SCNAction Which Removes The Red Emissio Colour Over The Passed Duration Parameter
let unHighlightAction = SCNAction.customAction(duration: duration) { (node, elapsedTime) in
let color = UIColor(red: CGFloat(1) - elapsedTime/CGFloat(duration), green: 0, blue: 0, alpha: 1)
let currentMaterial = self.geometry?.firstMaterial
currentMaterial?.emission.contents = color
}
//3. Create An SCNAction Sequence Which Runs The Actions
let pulseSequence = SCNAction.sequence([highlightAction, unHighlightAction])
//4. Set The Loop As Infinitie
let infiniteLoop = SCNAction.repeatForever(pulseSequence)
//5. Run The Action
self.runAction(infiniteLoop)
}
}
Lets say that we then create an SCNNode
with an SCNSphereGeometry
like so:
let blueNode = SCNNode()
let blueGeometry = SCNSphere(radius: 0.2)
blueGeometry.firstMaterial?.diffuse.contents = UIColor.blue
blueNode.geometry = blueGeometry
blueNode.position = SCNVector3(1.5, 0, -1.5)
blueNode.name = "BlueNode"
augmentedRealityView.scene.rootNode.addChildNode(redNode)
We can then call the highlight function
on this (or any SCNNode
) like so:
blueNode.highlightNodeWithDurarion(5)
Upvotes: 4