在 SwiftUI 中的 SceneKit 中对立方体进行动画处理

发布于 2025-01-10 06:28:28 字数 4779 浏览 0 评论 0原文

Swift 5,iOS 15

单击可旋转立方体,双击可在不同的轴上旋转它,但长按不会执行任何操作,除非我通过双击跟随它???

我在这里错过了什么吗?

import SwiftUI
import SceneKit


struct ContentView: View {

var body: some View {
    GameScene().environmentObject(settings)
}
}

struct GameScene: View {

@State var cameraNode = SCNNode()
@State var scene = SCNScene(named: "MyScene.scn")
@State var lightNode: SCNNode!
@State var lightNode2: SCNNode!
@State var cubeNode: SCNNode!
@State var direct = 6.0
@State var isReady = false
@State var viewAngle = 0

let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

var body: some View {
    if !isReady {
        Color.clear
        .task {
            let cubeGeometry = SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0.25)
            let redMaterial = SCNMaterial()
            redMaterial.diffuse.contents = UIColor.red
            let greenMaterial = SCNMaterial()
            greenMaterial.diffuse.contents = UIColor.green
            let blueMaterial = SCNMaterial()
            blueMaterial.diffuse.contents = UIColor.blue
            let yellowMaterial = SCNMaterial()
            yellowMaterial.diffuse.contents = UIColor.yellow
            let orangeMaterial = SCNMaterial()
            orangeMaterial.diffuse.contents = UIColor.orange
            let whiteMaterial = SCNMaterial()
            whiteMaterial.diffuse.contents = UIColor.white
            
            cubeGeometry.materials = [redMaterial, greenMaterial, orangeMaterial, blueMaterial, whiteMaterial, yellowMaterial]
            
            cubeNode = SCNNode(geometry: cubeGeometry)
            cubeNode.name = "cubeNode"
            cubeNode.eulerAngles = SCNVector3(x: 0, y: 0, z: 0)
            scene?.rootNode.addChildNode(cubeNode)
            
            cameraNode.camera = SCNCamera()
            cameraNode.position = SCNVector3(x: 0, y: 6, z: 6)
            cameraNode.eulerAngles = SCNVector3(x: GLKMathDegreesToRadians(-26), y: 0, z: 0)
            cameraNode.name = "cameraNode"
            scene?.rootNode.addChildNode(cameraNode)
            
            let light = SCNLight()
            light.type = SCNLight.LightType.omni
            lightNode = SCNNode()
            lightNode.light = light
            lightNode.position = SCNVector3(x: 4, y: 4, z: 4)
            scene?.rootNode.addChildNode(lightNode)
            
            let light2 = SCNLight()
            light2.type = SCNLight.LightType.omni
            lightNode2 = SCNNode()
            lightNode2.light = light2
            lightNode2.position = SCNVector3(x: -4, y: -4, z: -4)
            scene?.rootNode.addChildNode(lightNode2)
            isReady = true
        }
    } else {
       SceneView(
            scene: scene,
            pointOfView: cameraNode,
            options: [.autoenablesDefaultLighting,.allowsCameraControl, .rendersContinuously], delegate: SceneDelegate())
            .border(Color.red)
            .onTapGesture(count: 2) {
                Task(priority: .userInitiated) {
                    let rotate =
                    SCNAction.rotate(by: CGFloat(GLKMathDegreesToRadians(90)), around: SCNVector3(0,1,0), duration: 0.5)
                    await cubeNode.runAction(rotate)
                }
            }
            .onTapGesture(count: 1) {
                Task(priority: .userInitiated) {
                    let rotate =
                    SCNAction.rotate(by: CGFloat(GLKMathDegreesToRadians(90)), around: SCNVector3(1,0,0), duration: 0.5)
                    await cubeNode.runAction(rotate)
                }
            }
            .onLongPressGesture {
                Task(priority: .userInitiated) {
                    let shift = SCNAction.move(by: SCNVector3(0,-1,0), duration: 0.5)
                    await cameraNode.runAction(shift)
                    print("reg")
                    settings.poke = true
                }
            }
    }
}
}

class SharedView: ObservableObject {
@Published var poke = false
@Published var cubeColor = UIColor.red
@Published var location:CGPoint? = nil
@Published var viewAngle:Float = 0
static var shared = SharedView()
}

class SceneDelegate: NSObject, SCNSceneRendererDelegate {
var settings = SharedView.shared
var count = 0



@MainActor
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    if settings.poke {
        renderer.scene?.rootNode.enumerateChildNodes({ (node, _ ) in
            if node.name == "cameraNode"  {
                Task {
                    let shift = SCNAction.move(by: SCNVector3(0,-1,0), duration: 0)
                    await node.runAction(shift)
                    print("duck")
                    
                    settings.poke = false
                }
            }
        })
    }
}
}

Swift 5, iOS 15

A single click rotates the cube, a double click rotates it on a different axis, but a long press does nothing, unless I follow it by a double click???

Did I miss something here?

import SwiftUI
import SceneKit


struct ContentView: View {

var body: some View {
    GameScene().environmentObject(settings)
}
}

struct GameScene: View {

@State var cameraNode = SCNNode()
@State var scene = SCNScene(named: "MyScene.scn")
@State var lightNode: SCNNode!
@State var lightNode2: SCNNode!
@State var cubeNode: SCNNode!
@State var direct = 6.0
@State var isReady = false
@State var viewAngle = 0

let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

var body: some View {
    if !isReady {
        Color.clear
        .task {
            let cubeGeometry = SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0.25)
            let redMaterial = SCNMaterial()
            redMaterial.diffuse.contents = UIColor.red
            let greenMaterial = SCNMaterial()
            greenMaterial.diffuse.contents = UIColor.green
            let blueMaterial = SCNMaterial()
            blueMaterial.diffuse.contents = UIColor.blue
            let yellowMaterial = SCNMaterial()
            yellowMaterial.diffuse.contents = UIColor.yellow
            let orangeMaterial = SCNMaterial()
            orangeMaterial.diffuse.contents = UIColor.orange
            let whiteMaterial = SCNMaterial()
            whiteMaterial.diffuse.contents = UIColor.white
            
            cubeGeometry.materials = [redMaterial, greenMaterial, orangeMaterial, blueMaterial, whiteMaterial, yellowMaterial]
            
            cubeNode = SCNNode(geometry: cubeGeometry)
            cubeNode.name = "cubeNode"
            cubeNode.eulerAngles = SCNVector3(x: 0, y: 0, z: 0)
            scene?.rootNode.addChildNode(cubeNode)
            
            cameraNode.camera = SCNCamera()
            cameraNode.position = SCNVector3(x: 0, y: 6, z: 6)
            cameraNode.eulerAngles = SCNVector3(x: GLKMathDegreesToRadians(-26), y: 0, z: 0)
            cameraNode.name = "cameraNode"
            scene?.rootNode.addChildNode(cameraNode)
            
            let light = SCNLight()
            light.type = SCNLight.LightType.omni
            lightNode = SCNNode()
            lightNode.light = light
            lightNode.position = SCNVector3(x: 4, y: 4, z: 4)
            scene?.rootNode.addChildNode(lightNode)
            
            let light2 = SCNLight()
            light2.type = SCNLight.LightType.omni
            lightNode2 = SCNNode()
            lightNode2.light = light2
            lightNode2.position = SCNVector3(x: -4, y: -4, z: -4)
            scene?.rootNode.addChildNode(lightNode2)
            isReady = true
        }
    } else {
       SceneView(
            scene: scene,
            pointOfView: cameraNode,
            options: [.autoenablesDefaultLighting,.allowsCameraControl, .rendersContinuously], delegate: SceneDelegate())
            .border(Color.red)
            .onTapGesture(count: 2) {
                Task(priority: .userInitiated) {
                    let rotate =
                    SCNAction.rotate(by: CGFloat(GLKMathDegreesToRadians(90)), around: SCNVector3(0,1,0), duration: 0.5)
                    await cubeNode.runAction(rotate)
                }
            }
            .onTapGesture(count: 1) {
                Task(priority: .userInitiated) {
                    let rotate =
                    SCNAction.rotate(by: CGFloat(GLKMathDegreesToRadians(90)), around: SCNVector3(1,0,0), duration: 0.5)
                    await cubeNode.runAction(rotate)
                }
            }
            .onLongPressGesture {
                Task(priority: .userInitiated) {
                    let shift = SCNAction.move(by: SCNVector3(0,-1,0), duration: 0.5)
                    await cameraNode.runAction(shift)
                    print("reg")
                    settings.poke = true
                }
            }
    }
}
}

class SharedView: ObservableObject {
@Published var poke = false
@Published var cubeColor = UIColor.red
@Published var location:CGPoint? = nil
@Published var viewAngle:Float = 0
static var shared = SharedView()
}

class SceneDelegate: NSObject, SCNSceneRendererDelegate {
var settings = SharedView.shared
var count = 0



@MainActor
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    if settings.poke {
        renderer.scene?.rootNode.enumerateChildNodes({ (node, _ ) in
            if node.name == "cameraNode"  {
                Task {
                    let shift = SCNAction.move(by: SCNVector3(0,-1,0), duration: 0)
                    await node.runAction(shift)
                    print("duck")
                    
                    settings.poke = false
                }
            }
        })
    }
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文