1

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?

Bentaye
  • 9,403
  • 5
  • 32
  • 45
blue
  • 7,175
  • 16
  • 81
  • 179
  • 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 Sep 12 '17 at 01:31
  • that was it, to an extent. – blue Sep 12 '17 at 20:35

2 Answers2

0

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
    }

...

}
zeh
  • 1,197
  • 2
  • 14
  • 29
-1

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)
John Scalo
  • 3,194
  • 1
  • 27
  • 35
  • 1
    I thought this was the proper approach too, but in Xcode 10 this results in a 'must call designated initialiser' error. – Ash Apr 01 '19 at 13:04
  • 1
    Ash, try to call `super.init()` and then assign the geometry manually: `self.geometry = geometry` – bio May 31 '19 at 09:57