iosobjective-cswiftscenekitskscene

How to access text element from a .dae file in SceneKit?


I have a .dae file which is in shape of a Medal. Now this .dae file has a label element. I want to load this .dae file and want to update text on that label at runtime so user name will come there.

let originalNode = scene?.rootNode.childNode(withName: "label", recursively: true)
if let _text = originalNode?.geometry as? SCNText {
   _text.string = "Mohsin Khan"
}

// another way i tried
let originalNode = scene?.rootNode.childNode(withName: "label", recursively: true)
(originalNode?.geometry as! SCNText).string = "Mohsin Khan"

I have tried various ways but nothing is working. For

originalNode?.geometry as! SCNText // returning nil

Attaching screenshot of xcode showing elements: enter image description here


Solution

  • I've faced something similar... either remove the label node and substitute your own, or edit the .dae file and remove the label. Then you can add an SCNText where ever you want to put it. Something like this function allows you to bounce, rotate, and/or individually color all characters. You will have to play around with it some to get it into the right spot and the length of name string will vary. That complicates it - one solution is to center it into a fixed width [---Jim---] and don't go beyond a max length. That also has its challenges, but hopefully this will get you into the ballpark. This code does some special handling for spaces and line breaks (breakAt), you can remove that.

    func addSCNText(vGroupNode: SCNNode, vPosition: SCNVector3, vScale: SCNVector3, vString: String)
        {
            var vX: Float = 0
            for char in vString
            {
                let textGeometry = SCNText(string: String(char), extrusionDepth: 1.0)
                textGeometry.font = AppColor.endWaveFont!
                textGeometry.flatness = 0.2
                textGeometry.firstMaterial?.diffuse.contents = UIColor.red 
                let textNode = SCNNode(geometry: textGeometry)
                textNode.position.x = vX
                vX += 12
                if(breakAt != 0)
                {
                    vGroupNode.addChildNode(textNode)
                }
                else
                {
                    if(char != " ")
                    {
                        vGroupNode.addChildNode(textNode)
                    }
                }
            }
    
            gNodes.gameNodes.addChildNode(vGroupNode)
            vGroupNode.position = vPosition
            vGroupNode.scale = vScale
        }