Материал SceneKit мигает - PullRequest
0 голосов
/ 02 мая 2018

Я хочу, чтобы узел мигал (например, цикл от входного цвета до текущего firstMaterial). У узла есть материал, который используется многими другими узлами, но я не хочу, чтобы все узлы мигали (только выбранные узлы).

Мне удалось это сделать без SCNAction / SCNTransaction, но код грязный, очень сложный в обслуживании и должен вызываться в Update () ... Мне было интересно, может ли SCNAction / SCNTransaction помочь мне, но Я не знаю, как сделать это правильно.

1 Ответ

0 голосов
/ 03 мая 2018

Я верю, что нечто подобное укажет вам правильное направление.

Сначала мы создадим extension из SCNNode, чтобы мы могли использовать нашу функцию на любом 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)
    }

}

Допустим, мы затем создаем SCNNode с SCNSphereGeometry, например, так:

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)

Затем мы можем вызвать highlight function для этого (или любого SCNNode) следующим образом:

blueNode.highlightNodeWithDurarion(5)
...