swift - SceneKit 基础知识

标签 swift scenekit

我刚刚开始尝试 SceneKit。尝试使用非常简单的代码来创建一个对象,为其指定物理场,并通过点击为其指定速度。到目前为止,我能够应用物理学来创建它。我能够赋予它速度,但无法通过点击来实现这一点。我究竟做错了什么?我使用的技术与 SpriteKit 中使用的技术相同,但它在 SceneKit 中不起作用。请帮忙。

class GameViewController: UIViewController, SCNSceneRendererDelegate, SCNPhysicsContactDelegate {
let scene = SCNScene()

let shipNode = SCNNode()

let sceneView = SCNScene()

var cameraNode = SCNNode()
var floor = SCNFloor()
var floornod = SCNNode()

override func viewDidLoad() {
    super.viewDidLoad()

    let sceneView = self.view as SCNView
    sceneView.scene = scene
    sceneView.backgroundColor = SKColor.blueColor()
    sceneView.showsStatistics = true


    sceneView.scene?.physicsWorld.gravity = SCNVector3Make(0, -70, 0)
    sceneView.scene?.physicsWorld.speed = 1.0
    sceneView.delegate = self
    sceneView.jitteringEnabled = true
    sceneSetup()
    sceneView.pointOfView = cameraNode


    let ship = SCNScene(named: "art.scnassets/sphere.dae")!

    let shipNode = ship.rootNode.childNodeWithName("Sphere", recursively: true)!

    shipNode.position = SCNVector3Make(0, 50, 300)
    shipNode.scale = SCNVector3Make(10, 10, 10)
    shipNode.geometry?.firstMaterial?.diffuse.contents = UIImage(named: "ball.jpg")
    shipNode.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.Dynamic, shape: nil)
    shipNode.physicsBody?.restitution = 0.9
    shipNode.physicsBody?.velocity = SCNVector3Make(0, 100, 10)
    scene.rootNode.addChildNode(shipNode)
    println(shipNode.physicsBody?.velocity.y)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    shipNode.physicsBody?.velocity = SCNVector3Make(0, 200, 20) // code not working
    println(shipNode.physicsBody?.velocity.y) // prints nil instead of 200.00
}

    func sceneSetup() {

    cameraNode.camera = SCNCamera()
    cameraNode.camera?.zNear = 0.01
    cameraNode.camera?.zFar = 800
    cameraNode.camera?.xFov = 45
    cameraNode.camera?.yFov = 75


    cameraNode.rotation = SCNVector4Make(1, 0, 0, -25 * 0.017453293)
    cameraNode.position = SCNVector3Make(0, 150, 500)
    scene.rootNode.addChildNode(cameraNode)

    floornod.geometry = floor
    floornod.geometry?.firstMaterial?.diffuse.contents = "wood1.png"
    floornod.geometry?.firstMaterial?.locksAmbientWithDiffuse = true
    floornod.geometry?.firstMaterial?.diffuse.wrapS = SCNWrapMode.Repeat
    floornod.geometry?.firstMaterial?.diffuse.wrapT = SCNWrapMode.Repeat
    floornod.geometry?.firstMaterial?.diffuse.mipFilter = SCNFilterMode.Linear
    floornod.physicsBody = SCNPhysicsBody(type: SCNPhysicsBodyType.Static, shape: nil)
    floornod.position = SCNVector3Make(0, 0, 0)

    scene.rootNode.addChildNode(floornod)

}

}

第一个 println 给出的结果是 100.00。 每次我点击时,touchesBegan 中的 println 都会给出 nil 结果。

非常感谢任何帮助。谢谢。

最佳答案

您可以在 viewDidLoad 方法中使用 let ShipNode = ... 定义一个新的局部变量。这个得到一个物理体并被放入场景中。

这与您定义为类一部分的实例变量shipNode 是分开的。该对象永远不会获得任何进一步的配置,因此当您在 touchesBegan 中访问它时,它没有物理体,并且可选链接会导致查询其速度的整个表达式返回 nil。

大概您想删除 viewDidLoad 中的 let,以便配置实例变量而不是隐藏它们。

关于swift - SceneKit 基础知识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26171783/

相关文章:

ios - Scenekit:两个 SCNNode 之间的角度

ios - 子类化 GMSMarker 和 GMSMapViewDelegate didTapMarker

swift - 无法使用 Swift Codable 解析响应

ios - 如何: Report download progress for CloudKit operations

swift - 是否可以像 SKScene 一样在 SCNScene 或 SCNNode 中使用 "update(_ currentTime: TimeInterval)"?

ios - Deinit 永远不会被调用,内存问题

swift - 如何在我的 Scenekit.scene 之上创建一个 HUD

swift - 了解 ARKit 世界变换矩阵

swift - 不确定在 swift 中使用什么数据类型

ios - "Command failed due to signal: Segmentation fault: 11"- 问题是什么?