How can I add a Scenekit Scene to a SwiftUI view?
I tried the following Hello World, using the standard Ship Scene example...
import SwiftUI
import SceneKit
struct SwiftUIView : View {
var body: some View {
ship()
Text("hello World")
}
But it didn't work:
Rawbee's answer does the job if you are creating a SwiftUIView
inside a Game project (the default game project that Xcode will create for you)
But if you are in a Single View App project, you can create the same SceneView like this:
drag the art.scnassets
folder (which contains 2 files: ship.scn
and texture.png
) from your game project to your Single View App project.
In your Single View App project create a new SwiftUI file — I called it: ScenekitView
. This is a structure which conforms to the UIViewRepresentable
protocol
Copy and paste the code below to this file and turn on live preview mode
import SwiftUI
import SceneKit
struct ScenekitView : UIViewRepresentable {
let scene = SCNScene(named: "art.scnassets/ship.scn")!
func makeUIView(context: Context) -> SCNView {
// create and add a camera to the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
// place the camera
cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
// create and add a light to the scene
let lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light!.type = .omni
lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
scene.rootNode.addChildNode(lightNode)
// create and add an ambient light to the scene
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = .ambient
ambientLightNode.light!.color = UIColor.darkGray
scene.rootNode.addChildNode(ambientLightNode)
// retrieve the ship node
let ship = scene.rootNode.childNode(withName: "ship", recursively: true)!
// animate the 3d object
ship.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: 2, z: 0, duration: 1)))
// retrieve the SCNView
let scnView = SCNView()
return scnView
}
func updateUIView(_ scnView: SCNView, context: Context) {
scnView.scene = scene
// allows the user to manipulate the camera
scnView.allowsCameraControl = true
// show statistics such as fps and timing information
scnView.showsStatistics = true
// configure the view
scnView.backgroundColor = UIColor.black
}
}
#if DEBUG
struct ScenekitView_Previews : PreviewProvider {
static var previews: some View {
ScenekitView()
}
}
#endif
I'm not a pro but this code worked for me (Xcode 11 beta 4)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With