我有 "Explode.scnp"
SceneKit
文件。它已经配置好了,纹理已经设置好了。
我们如何在 SwiftUI 中使用它?
例如,单击按钮后,背景将动画一次。
var body: some View {
ZStack {
VStack {
Button(action: {
Particles()
}) {
Text("Animate")
}
}
}
}
此代码适用于 scn。但是如何将它与 scnp 一起使用?
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.3.1。
当我尝试创建一个新文件时,我有这个:
扩展名是SKS ...有什么想法吗?
根据@Asperi 版本重新编写代码:
import SwiftUI
import SceneKit
struct ScenekitView : UIViewRepresentable {
@Binding var exploding: Bool
//let scene = SCNScene(named: "SceneKit.scnassets/Explode.scnp")!
let scene = SCNScene(named: "SceneKit.scnassets/scene.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: "blow", 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 exploding {
if let scene = scene.rootNode.childNode(withName: "SceneKit.scnassets/scene", recursively: false),
let particles = SCNParticleSystem(named: "SceneKit.scnassets/Explode", inDirectory: nil) {
let node = SCNNode()
node.addParticleSystem(particles)
node.position = scene.position
scnView.scene?.rootNode.addChildNode(node)
scene.removeFromParentNode()
}
}
}
}
与路径名相关的错误...
// retrieve the ship node
这里。尝试过 .sks、.scnp ... 有什么想法吗?
最佳答案
这是带有演示的修改代码。使用 Xcode 11.4/macOS 10.15.4 测试
注意:由于我不知道您的项目结构,所有依赖的资源文件都被添加为资源(不在 Assets 中)。以防万一。
struct DemoSceneKitParticles: View {
@State private var exploding = false
var body: some View {
VStack {
ScenekitView(exploding: $exploding)
Button("BOOM") { self.exploding = true }
}
}
}
struct ScenekitView : NSViewRepresentable {
@Binding var exploding: Bool
let scene = SCNScene(named: "ship.scn")!
func makeNSView(context: NSViewRepresentableContext<ScenekitView>) -> 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 = NSColor.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 updateNSView(_ 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 = NSColor.black
if exploding {
if let ship = scene.rootNode.childNode(withName: "ship", recursively: true),
let particles = SCNParticleSystem(named: "Explosion", inDirectory: nil) {
let node = SCNNode()
node.addParticleSystem(particles)
node.position = ship.position
scnView.scene?.rootNode.addChildNode(node)
ship.removeFromParentNode()
}
}
}
}
更新:iOS 的变体
使用 Xcode 11.4/iOS 13.4 测试
完整的模块代码(资源文件和以前一样在顶层)
import SwiftUI
import SceneKit
struct DemoSceneKitParticles: View {
@State private var exploding = false
var body: some View {
VStack {
ScenekitView(exploding: $exploding)
Button("BOOM") { self.exploding = true }
}
}
}
struct ScenekitView : UIViewRepresentable {
@Binding var exploding: Bool
let scene = SCNScene(named: "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 exploding {
if let ship = scene.rootNode.childNode(withName: "ship", recursively: true),
let particles = SCNParticleSystem(named: "Explosion", inDirectory: nil) {
let node = SCNNode()
node.addParticleSystem(particles)
node.position = ship.position
scnView.scene?.rootNode.addChildNode(node)
ship.removeFromParentNode()
}
}
}
}
struct DemeSKParticles_Previews: PreviewProvider {
static var previews: some View {
DemoSceneKitParticles()
}
}
关于ios - 如何在 SwiftUI 中使用 "*.scnp"文件进行按钮单击(iOS)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62046891/