0

I have been trying to get this to work for 3 days now. For my project I need to display changing values as 3d text rendered in an AR application written in Swift for iOS.

What I already found: I can use the following code to generate a static text in 3d at a certain location. I can put it in the ViewDidLoad method of my ViewController so that it loads once on startup.

let text = SCNText(string: "Let's begin!", extrusionDepth: 1)

//Create material
let material = SCNMaterial()
material.diffuse.contents = UIColor.green
text.materials = [material]

//Create Node object
let textNode = SCNNode()
textNode.scale = SCNVector3(x:0.004,y:0.004,z:0.004)
textNode.geometry = text
textNode.position = SCNVector3(x: 0, y:0.02, z: -0.5)

sceneView.scene.rootNode.addChildNode(textNode)

Now my problem is I cannot get it to change periodically and say count up to 10000.

I have tried quite a few ideas, but none showed the numbers counting up.

UPDATE: I am having trouble removing the node after I create it. Also I do not know exactly when I have to remove it.

I am receiving a bad access code=1 error. The problem seems to lie with the finding & removing the node, because if I comment the line the app launches. It may have sth to do with access privileges.

This is my function:

func updateSCNText2 (incomingInt: Int) {

    // create new text
    let text = SCNText(string: String(incomingInt), extrusionDepth: 1)
    //  create material
    let material = SCNMaterial()
    material.diffuse.contents = UIColor.green
    text.materials = [material]

    //Create Node object
    let textNode = SCNNode()
    textNode.name = "textNodeName"
    textNode.scale = SCNVector3(x:0.004,y:0.004,z:0.004)
    textNode.geometry = text
    textNode.position = SCNVector3(x: 0, y:0.02, z: -0.5)

    //  add new node to root node
    sceneView.scene.rootNode.addChildNode(textNode)

    //  find & remove previous node (childNodeWithName)
    sceneView.scene.rootNode.childNode(withName: "textNodeName", recursively: false)?.removeFromParentNode()

}

Where I am calling the function:

var k = 0

func renderer(_ renderer: SCNSceneRenderer,
              updateAtTime time: TimeInterval) {

    print(k)
    updateSCNText2(incomingInt:  k)
    k = k+1
}

Thank you so much for taking the time!

Sam
  • 51
  • 1
  • 7
  • I would every time a change occurs (say the count changes from 20 -> 21) find the node (by giving it a name: textNode.name), delete that node and place another node with same name and same position in the scene. – Peter de Vries Jan 03 '18 at 10:40

1 Answers1

0

Best way to do this is using NSTimer

Firstly, set textNode & a counter var at the top of your ViewController class

var textNode: SCNNode!

var counter = 0

inside of viewDidLoad add the NSTimer call:

var timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)

leave you original textNode creation method in ViewDidLoad except textNode is now var

this is the update function

@objc func update() {

    counter += 1

    // remove the old textNode

    textNode.removeFromParentNode()

        // create new text
        let text = SCNText(string: String(counter), extrusionDepth: 1)
        //  create material
        let material = SCNMaterial()
        material.diffuse.contents = UIColor.green
        text.materials = [material]

        //Create Node object
    textNode = SCNNode()
    textNode.scale = SCNVector3(x:0.004,y:0.004,z:0.004)
    textNode.geometry = text
    textNode.position = SCNVector3(x: 0, y:0.02, z: -0.5)

    //  add new node to root node
    self.sceneView.scene.rootNode.addChildNode(textNode)

}

Note: this code works, just tested it out in a playground. Can provide if needed.

Clay
  • 1,721
  • 2
  • 10
  • 18