[英]How to use "*.scnp" file in SwiftUI for button click (iOS)?
I have "Explode.scnp"
SceneKit
file.我有
"Explode.scnp"
SceneKit
文件。 It's already configured, the texture has been set.它已经配置好了,纹理已经设置好了。
How we can use it in SwiftUI?我们如何在 SwiftUI 中使用它? For example, after the button clicks the background will be animated once.
例如,单击按钮后,背景将动画一次。
var body: some View {
ZStack {
VStack {
Button(action: {
Particles()
}) {
Text("Animate")
}
}
}
}
This code works for scn.此代码适用于 scn。 but how to use it with scnp?
但是如何将它与 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
Moreover, Xcode version is 11.3.1.此外,Xcode 版本是 11.3.1。 When I try to create a new file I have this:
当我尝试创建一个新文件时,我有这个:
And the extension is SKS... any ideas?扩展名是SKS ...有什么想法吗?
Reworked the code according to @Asperi version:根据@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()
}
}
}
}
Errors related to the path names...与路径名相关的错误...
// retrieve the ship node
here.这里。 Tried.sks, .scnp... any ideas?
Tried.sks、.scnp ......有什么想法吗?
Here is modified code with demo.这是带有演示的修改代码。 Tested with Xcode 11.4 / macOS 10.15.4
使用 Xcode 11.4 / macOS 10.15.4 测试
Note: as I don't know your project structure, all dependent resource files were added as Resources (not in Assets).注意:由于我不知道您的项目结构,所有依赖的资源文件都作为资源添加(而不是在资产中)。 Just in case.
以防万一。
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()
}
}
}
}
Update: variant for iOS更新:iOS 的变体
Tested with Xcode 11.4 / iOS 13.4使用 Xcode 11.4 / iOS 13.4 测试
Full module code (resource files as before at top level)完整的模块代码(资源文件和以前一样在顶层)
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()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.