[英]SwiftUI - how to add a Scenekit Scene
How can I add a Scenekit Scene to a SwiftUI view?如何将 Scenekit 场景添加到 SwiftUI 视图?
I tried the following Hello World, using the standard Ship Scene example...我尝试了以下 Hello World,使用标准 Ship Scene 示例...
import SwiftUI
import SceneKit
struct SwiftUIView : View {
var body: some View {
ship()
Text("hello World")
}
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) Rawbee的回答做的工作,如果你正在创建一个
SwiftUIView
一个游戏项目中(默认的游戏项目,该项目的Xcode会为你创建)
But if you are in a Single View App project, you can create the same SceneView like this:但是如果你在一个Single View App项目中,你可以像这样创建相同的 SceneView:
drag the art.scnassets
folder (which contains 2 files: ship.scn
and texture.png
) from your game project to your Single View App project.将
art.scnassets
文件夹(其中包含 2 个文件: ship.scn
和texture.png
)从您的游戏项目ship.scn
您的Single View App项目中。
In your Single View App project create a new SwiftUI file — I called it: ScenekitView
.在你的Single View App项目中创建一个新的 SwiftUI 文件——我称之为:
ScenekitView
。 This is a structure which conforms to the UIViewRepresentable
protocol这是一个符合
UIViewRepresentable
协议的结构
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)我不是专业人士,但此代码对我有用(Xcode 11 beta 4)
In order for this to work, your SwiftUI View must conform to UIViewRepresentable
.为了使其工作,您的 SwiftUI 视图必须符合
UIViewRepresentable
。 There's more info about that in Apple's tutorial: Interfacing with UIKit . Apple 的教程中提供了更多相关信息: Interfaceting with UIKit 。
import SwiftUI
struct SwiftUIView : UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
return UIStoryboard(name: "Main", bundle: Bundle.main).instantiateInitialViewController()!.view
}
func updateUIView(_ view: UIView, context: Context) {
}
}
#if DEBUG
struct SwiftUIView_Previews : PreviewProvider {
static var previews: some View {
SwiftUIView()
}
}
#endif
Note that you'll have to turn on live preview to see it working.请注意,您必须打开实时预览才能看到它的工作原理。
You don't need use UIViewRepresentable
anymore.您不再需要使用
UIViewRepresentable
了。 Here's an update code for SwiftUI这是 SwiftUI 的更新代码
import SwiftUI
import SceneKit
struct ContentView: View {
var scene: SCNScene? {
SCNScene(named: "Models.scnassets/Avatar.scn")
}
var cameraNode: SCNNode? {
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(x: 0, y: 0, z: 2)
return cameraNode
}
var body: some View {
SceneView(
scene: scene,
pointOfView: cameraNode,
options: [
.allowsCameraControl,
.autoenablesDefaultLighting,
.temporalAntialiasingEnabled
]
)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.