Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using SpriteKit inside SwiftUI

I am having an issue when creating a SpriteKit scene within SwiftUI. I created this project initially as a SwiftUI project.

Here is the code I have so far:

ContentView.swift:

/// Where the UI content from SwiftUI originates from.
struct ContentView : View {
    var body: some View {
        // Scene
        SceneView().edgesIgnoringSafeArea(.all)
    }
}

SceneView.swift:

/// Creates an SKView to contain the GameScene. This conforms to UIViewRepresentable, and so can be used within SwiftUI.
final class SceneView : SKView, UIViewRepresentable {
    
    // Conformance to UIViewRepresentable
    func makeUIView(context: Context) -> SKView {
        print("Make UIView")
        return SceneView(frame: UIScreen.main.bounds)
    }
    func updateUIView(_ uiView: SKView, context: Context) {
        print("Update UIView")
    }
    
    // Creating scene
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        let scene = Scene(size: UIScreen.main.bounds.size)
        presentScene(scene)
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Scene.swift:

/// The scene for the game in SpriteKit.
final class Scene : SKScene {

    override func didMove(to view: SKView) {
        super.didMove(to: view)
    
        print("Scene didMove:")
    }
}

Problem

The problem is that the scene is reloading multiple times, as shown by the logs (because there are prints in the code):

Scene didMove:

Make UIView

Scene didMove:

Update UIView


As you can see, Scene didMove: is printed twice. I only want this to be called once, as I want to create my sprites here. Any ideas?

like image 331
George Avatar asked Jun 16 '19 00:06

George


People also ask

Can you use SpriteKit with SwiftUI?

Even though the default Game Xcode Template creates the project based on a UIKit application, you can create a SwiftUI app and put your SpriteKit game inside it without any hustle thanks to the SpriteView view!

What is SpriteKit in Swift?

SpriteKit is a general-purpose framework for drawing shapes, particles, text, images, and video in two dimensions. It leverages Metal to achieve high-performance rendering, while offering a simple programming interface to make it easy to create games and other graphics-intensive apps.

What is the difference between SceneKit and SpriteKit?

You can assume SpriteKit is at Top of the SceneKit, As using SceneKit you can add 3D models into Augmented Reality while SpriteKit is used to add extra sprites onto the model. In short SpriteKit is revolution in Gaming.


1 Answers

SwiftUI 2

There is now a native view responsible for displaying a SKScene - it's called SpriteView.

Assuming we have a simple SKScene:

class Scene: SKScene {
    override func didMove(to view: SKView) {
        ...
    }
}

we can use a SpriteView to display it directly in a SwiftUI view:

struct ContentView: View {
    var scene: SKScene {
        let scene = Scene()
        scene.size = CGSize(width: 300, height: 400)
        scene.scaleMode = .fill
        return scene
    }

    var body: some View {
        SpriteView(scene: scene)
            .frame(width: 300, height: 400)
            .edgesIgnoringSafeArea(.all)
    }
}

You can find more information here:

  • How to integrate SpriteKit using SpriteView.
like image 171
pawello2222 Avatar answered Oct 24 '22 22:10

pawello2222