Search code examples
iosswiftsprite-kitcomponentsgameplay-kit

How to add components to sprites within editor with gameplaykit


I have a component:

class Test: GKComponent {
    override init() {
        super.init()
        print("init ran")
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        print("coder init ran")
    }
}

I also have a subclass:

class Testing: SKSpriteNode {

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

    }
}

So in my scene editor, I have a sprite. In the editor I subclass it to Testing.

Also in the scene editor I add the component Test.

When I run the project, it runs fine, and it prints both print statements in the Component subclass.

  1. Why does it use both init functions and how do I get it to use only 1?

  2. How would I add something in this component like an action or something... Say I want the sprite to rotate for example? How would I do this?

Thank you for any help...


Solution

  • 1) I guess you do not understand what a component is, A component is not the same thing as an SKSpriteNode, in fact they are 2 completely different things with almost no relationship to each other. When you place a node on the scene with the scene builder, behind the scenes it makes an instance of GKEntity and GKSKComponent automatically. GKSKComponent is the component that holds the SKSpriteNode. Your Test component is a component that does something else. Everything is compartmentalized. Best example, think of a bicycle. The wheels are a component, the chain is a component, the brakes are a component, each that serve a very unique purpose. You need to create (init) all of these objects to get a bicycle.

    2) To get other components to work with your SKSpriteNode, you need to get to the entity. The component should have access to it, so you just need to do self.entity. Then you need to find the GKSKComponent, which will have a link to the node you are looking for so that you may apply actions to it.

    Here is my class I have made to make it easier for Components to access the node

    import GameplayKit
    
    class NodeComponent : GKComponent
    {
        public private(set) lazy var node : SKNode = self.entity!.component(ofType: GKSKNodeComponent.self)!.node
    
        func resetNode(to node:SKNode)
        {
            self.node = node;
        }
    
    }