1
votes

Ok, I need to subclass SCNNode because I have different SCNNodes with different "abilities" in my game (I know people don't usually subclass SCNNode but I need to)

I have followed every other question like Subclassing SCNNode and Creating a subclass of a SCNNode but continue to get this error:

fatal error: use of unimplemented initializer 'init()' for class 'LittleDude.Dude'

Where Dude is the name of my SCNNode subclass.

Following the second question, because of classing issues this is how I attempt to get the SCNNode from my .dae scene and assign it to my Dude():

var theDude = Dude(geometry: SCNSphere(radius: 0.1)) //random geometry first
var modelScene = SCNScene(named: "art.scnassets/ryderFinal3.dae")!
if let d = modelScene.rootNode.childNodes.first
{
    theDude.transform = d.transform
    theDude.geometry = d.geometry
    theDude.rotation = d.rotation
    theDude.position = d.position
    theDude.boundingBox = d.boundingBox
    theDude.geometry?.firstMaterial = d.geometry?.firstMaterial
}
print("DUDE: ", theDude)

Then in my Dude class:

class Dude: SCNNode {

    init(geometry: SCNGeometry) {
        super.init()

        center(node: self)
        self.scale = SCNVector3(x: modifier, y: modifier, z: modifier)
        //theDude.transform = SCNMatrix4Mult(theDude.transform, SCNMatrix4MakeRotation(360, 0, 1, 0))
        //theDude.worldOrientation = .
        //self.theDude.position = SCNVector3Make(0, 0, -1)

        for s in animScenes {
            if let anim = animationFromSceneNamed(path: s)
            {
                animations.append(anim)
                anim.usesSceneTimeBase = true
                anim.repeatCount = Float.infinity
                self.addAnimation(anim, forKey: anim.description)
            }
        }
    }
}

/* Xcode required this */
required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented222")
}

The error gets drawn on first line of this custom class and happens when I try to clone and add the custom SCNNode to my scene:

func makeDude(hitPosition: SCNVector3) {
    //print("DUDE")
    let clone = theDude.clone() as? SCNNode
    clone?.position = hitPosition
    self.sceneView.scene.rootNode.addChildNode(clone!)
}

Even though I cast to SCNNode to try to avoid an error. How can I just clone and use my custom SCNNode in my scene? What is wrong here?

2
It looks like the runtime is looking for a function declared as init() (i.e. no parameters). As an experiment, what happens when you duplicate your current init(geometry: SCNGeometry) and simply rename the declaration to init()?Michael Dautermann
that was it, to an extent.skyguy

2 Answers

0
votes

If you subclass SCNNode and override its initializer init(geometry: SCNGeometry?) then you'll need to call the same initalizer of super during your init. Try changing

super.init()

to

super.init(geometry: geometry)
0
votes

Just to make clear, this answer is hidden on the comments of a previous answer, so to avoid the confusion here is the answer fully spelled out:


class NodeSubClass: SCNNode {

init(geometry: SCNGeometry?){
        super.init()
        self.geometry = geometry
    }

...

}