0

Good day, In Spritekit my code fails because I am obliged by GKComponent to implement:

a. a "required init" I do not need. b. At run time it calls this instead of my normal init() and fails. c. super.init(coder: aDecoder) does not solve my problem of calling it

Question: A Solution to call my init instead of this forced required init

In other answers suggest a solution to use super.init(coder: aDecoder) but it has not solved my problem of not calling it.

required init?(coder aDecoder: NSCoder) {

    fatalError("init(coder:) has not been implemented")
}

//This code is supposed to add a simple eplipse under the sprite to make //a shadow effect by making it a GKComponent and add it to a GKEntity.

     import Foundation
        import GameplayKit
        import SpriteKit

    //GKEntity to add GKComponents
        class Entity: GKEntity{    

    //A variable that is a GKComponent defined as ShadowComponent: GKComponent    

var shadow: ShadowComponent

//My init

override init() {

shadow = ShadowComponent(size: CGSize(width: 50, height: 50), offset: CGPoint(x: 0, y: -20))

super.init()
addComponent(shadow)

        }

//Forced by compiler to have it

**required init?(coder aDecoder: NSCoder) {

            fatalError("init(coder:) has not been implemented")
        }**

    }

2 Answers2

0

The required init is required by the system; it will be called when the system autoload your component. With the interface builder for example. You can take a look at this answer for more informations. Is your entity added in the Scene editor?

So you need to focus on the way your Entity is created. If you want to call your custom init, you need to init it programmatically.

I can suggest to make the required init work, if you want to keep using your Entity in your Scene editor:

required init?(coder aDecoder: NSCoder) {
  shadow = ShadowComponent(size: CGSize(width: 50, height: 50), offset: CGPoint(x: 0, y: -20))
  super.init(coder: aDecoder)
  addComponent(shadow)
}
Steve G.
  • 589
  • 5
  • 13
0

All variables need to have a value assigned to it before init. Because your shadow does not have a value, the compiler is forcing you to override required init so that you can give shadow a value.

To fix this, just make shadow lazy:

lazy var shadow = 
{
    [unowned self] in
    let shadow = ShadowComponent(size: CGSize(width: 50, height: 50), offset: CGPoint(x: 0, y: -20))
    addComponent(shadow)
    return shadow
}()

Then, the first time shadow is used, it will create and add the component for you.

The only reason we need to made it lazy is because of the addComponent aspect of it. Your code could be written like this to avoid having to use a lazy, but you would need to call a function to add your component.

let shadow = ShadowComponent(size: CGSize(width: 50, height: 50), offset: CGPoint(x: 0, y: -20))

func addComponents(){
    addComponent(shadow)
}
Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44