从ViewController访问SceneKit-Node

时间:2016-03-12 18:00:59

标签: ios swift scenekit

我试图在Swift中构建一个SceneKit-App。这个应用程序应该有一个SpriteKit-Overlay。我的问题是,我可以从我的ViewController中的SpriteKit访问LabelNode,但是不能更改SceneKit中Cube-Node的位置值,尽管我可以访问该节点。因为我是一个新手,如果有人能指出我正确的方向,那将是非常好的。

class GameViewController: UIViewController {

    var sceneView: SCNView!
    var spriteScene: SpriteKitOverlay!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
        self.sceneView.scene = SceneKitScene()
        self.sceneView.backgroundColor = UIColor.brownColor()
        self.view.addSubview(self.sceneView)

        self.spriteScene = SpriteKitOverlay(size: self.view.bounds.size)
        self.sceneView.overlaySKScene = self.spriteScene

        SceneKitScene().cubeNode.position = SCNVector3(0,10,0)
        spriteScene.labelTest.text = "Changed label"
        print(SceneKitScene().cubeNode.position)
    }
}

class SpriteKitOverlay: SKScene {

    var labelTest: SKLabelNode!

    override init(size: CGSize) {
        super.init(size: size)

        self.labelTest = SKLabelNode(text: "Label text")
        self.labelTest.fontColor = UIColor.whiteColor()
        self.labelTest.fontSize = 24
        self.labelTest.position = CGPoint(x: size.width/2, y: size.height/2)

        self.addChild(self.labelTest)

    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

}


class SceneKitScene: SCNScene {

    var cubeNode: SCNNode!
    var cameraNode: SCNNode!
    var lightNode: SCNNode!

    override init() {
        super.init()

        let cube = SCNBox(width: 3, height: 3, length: 3, chamferRadius: 0)
        let cubeMaterial = SCNMaterial()
        cubeMaterial.diffuse.contents = UIColor.blueColor()
        cube.materials = [cubeMaterial]
        self.cubeNode = SCNNode(geometry: cube)
        self.cubeNode.position = SCNVector3(0,0,0)
        self.cubeNode.runAction(SCNAction.repeatActionForever(SCNAction.rotateByX(0, y: 0.01, z: 0, duration: 1.0/60.0)))

        let camera = SCNCamera()
        camera.xFov = 60
        camera.yFov = 60

        let ambientLight = SCNLight()
        ambientLight.type = SCNLightTypeAmbient
        ambientLight.color = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1.0)

        let cameraConstraint = SCNLookAtConstraint(target: self.cubeNode)
        cameraConstraint.gimbalLockEnabled = true

        self.cameraNode = SCNNode()
        self.cameraNode.camera = camera
        self.cameraNode.constraints = [cameraConstraint]
        self.cameraNode.light = ambientLight
        self.cameraNode.position = SCNVector3(x: 5, y: 5, z: 5)

        let omniLight = SCNLight()
        omniLight.type = SCNLightTypeOmni

        self.lightNode = SCNNode()
        self.lightNode.light = omniLight
        self.lightNode.position = SCNVector3(x: -3, y: 5, z: 3)

        self.rootNode.addChildNode(self.cubeNode)
        self.rootNode.addChildNode(self.cameraNode)
        self.rootNode.addChildNode(self.lightNode)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }


}

1 个答案:

答案 0 :(得分:1)

当您致电SceneKitScene().cubeNode.position = SCNVector3(0,10,0)时,您正尝试更新新创建的cubeNode.position上的SceneKitScene

尝试将GameViewController更改为:

class GameViewController: UIViewController {

    var sceneView: SCNView!
    // create new instance variable to hold current sceneKitScene
    var sceneKitScene: SceneKitScene!
    var spriteScene: SpriteKitOverlay!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
        // save SceneKitScene to instance variable
        self.sceneKitScene = SceneKitScene()
        self.sceneView.scene = self.sceneKitScene
        self.sceneView.backgroundColor = UIColor.brownColor()
        self.view.addSubview(self.sceneView)

        self.spriteScene = SpriteKitOverlay(size: self.view.bounds.size)
        self.sceneView.overlaySKScene = self.spriteScene

        // update cubeNode position in active sceneKitScene
        sceneKitScene.cubeNode.position = SCNVector3(0,10,0)
        spriteScene.labelTest.text = "Changed label"
        print(SceneKitScene().cubeNode.position)
    }
}

这会创建一个新的实例变量来保存当前的SceneKitScene(与您当前的SpriteKitOverlay相同)。然后,您可以使用此变量来访问和更新屏幕上当前cubeNode的位置。