不能改变材料

时间:2015-01-30 04:45:16

标签: ios swift scenekit

我添加了一行代码(其中显示// LINE CHANGED)将材质更改为蓝色。但是,当我加载游戏时,默认的船只保持正常纹理。关于为什么会发生这种情况的任何想法?我可以在我制作的立方体上更换材料,但出于某种原因,船舶材料没有变化。

override func viewDidLoad() {
    super.viewDidLoad()

    // create a new scene
    let scene = SCNScene(named: "art.scnassets/ship.dae")!

    // 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 = SCNLightTypeOmni
    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 = SCNLightTypeAmbient
    ambientLightNode.light!.color = UIColor.darkGrayColor()
    scene.rootNode.addChildNode(ambientLightNode)

    // retrieve the ship node
    let ship = scene.rootNode.childNodeWithName("ship", recursively: true)!


    //LINE CHANGED
    ship.geometry?.firstMaterial?.diffuse.contents = UIColor.blueColor()
    //LINE CHANGED

    // animate the 3d object\
    ship.runAction(SCNAction.repeatActionForever(SCNAction.rotateByX(0, y: 2, z: 0, duration: 1)))

    // retrieve the SCNView
    let scnView = self.view as SCNView

    // set the scene to the view
    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.blackColor()

    // add a tap gesture recognizer
    let tapGesture = UITapGestureRecognizer(target: self, action: "handleTap:")
    let gestureRecognizers = NSMutableArray()
    gestureRecognizers.addObject(tapGesture)
    if let existingGestureRecognizers = scnView.gestureRecognizers {
        gestureRecognizers.addObjectsFromArray(existingGestureRecognizers)
    }
    scnView.gestureRecognizers = gestureRecognizers
}

2 个答案:

答案 0 :(得分:3)

ship.geometry是零。所以该线的其余部分将无效。

如果您检查xcode中的文件“ship.dae”,您将看到名为“ship”的节点没有附加几何体,但它有一个名为“shipMesh”的子节点拥有几何体。

答案 1 :(得分:0)

Toyos already covered the answer pretty well,但我想添加一些评论太长的建议...

Swift中的可选链接存在固有的危险(或者在ObjC中可能是nil的消息传递) - 如果它失败了,它会默默地这样做。你可能会说这比崩溃更糟糕,但调试起来比较困难。

不要编写longChain?.of?.optionalCalls(),而是考虑使用optional bindingif let)作为其中的一部分,以便您可以看到链由于零值而中断的位置。它提供了更多代码,但它可以让您检查链中的每一步,并以对您的应用最有意义的方式处理故障。这甚至可以是一个调试策略 - 如果你有一行看似无效的可选链接调用,请用等效的if let语句嵌套替换它,直到找到问题为止。 (如果你愿意,可以在你修好它之后再回到可选链接。)

许多人对隐含的无包装选项感到苛刻,但有些时候和地方都有用。我说这是其中之一 - 你需要通过的选项链是你可以在应用程序构建时确保的(不是在源编译时),因为它是DAE的配置在您的应用中发货。 (这与IBOutlet通常为IUO的基本原理基本相同。)写ship.geometry!.firstMaterial!.contents会提醒您DAE的内容与您认为的内容之间的不匹配,因为您' d崩溃解除引用geometry