在 SwiftUI 中的 SceneKit 中对立方体进行动画处理
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论