如何将Scenekit场景添加到SwiftUI视图?
我使用标准的Ship Scene示例尝试了以下Hello World ...
import SwiftUI
import SceneKit
struct SwiftUIView : View {
var body: some View {
ship()
Text("hello World")
}
答案 0 :(得分:6)
如果您是在 Game 项目(Xcode将为您创建的默认游戏项目)中创建SwiftUIView
的话,Rawbee的答案就会起作用。
但是,如果您在 Single View App 项目中,则可以创建相同的SceneView,如下所示:
从您的 game 项目中将art.scnassets
文件夹(包含2个文件:ship.scn
和texture.png
拖到 Single View App 项目。
在您的 Single View App 项目中创建一个新的SwiftUI文件-我将其命名为:ScenekitView
。这是符合UIViewRepresentable
协议的结构
将下面的代码复制并粘贴到此文件中,然后打开实时预览模式
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
我不是专业人士,但是这段代码对我有用(Xcode 11 beta 4)
答案 1 :(得分:6)
您不再需要使用 UIViewRepresentable
。这是 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()
}
}
答案 2 :(得分:1)
为使此工作正常,您的SwiftUI视图必须符合UIViewRepresentable
。 Apple的教程中提供了有关此内容的更多信息:Interfacing 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
请注意,您必须打开实时预览才能看到它的正常运行。