无法更改 material

cannot change material

我添加了一行代码(其中写着 //LINE CHANGED)将 material 更改为蓝色。但是,当我加载游戏时,默认飞船仍保持正常纹理。关于为什么会发生这种情况的任何想法?我可以在我制作的立方体上更改 material 就好了,但由于某些原因,船 material 没有改变。

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
}

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

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

,但我想添加一些太长的建议,无法发表评论...

Swift 中的可选链接(或者在 ObjC 中可以为 nil 的消息,就此而言)存在固有的危险——如果它失败了,它会默默地这样做。您可能会说这没有崩溃那么糟糕,但更难调试。

与其编写 longChain?.of?.optionalCalls(),不如考虑对它的一部分使用 optional binding (if let),这样您就可以看到由于 nil 值而导致链断裂的位置。这是更多的代码,但它可以让您检查链条的每个步骤并以对您的应用程序最有意义的方式处理故障。这甚至可以作为一种调试策略——如果您有一行似乎什么都不做的可选链接调用,请将其替换为等效的 if let 语句嵌套,直到您找到问题为止。 (如果你愿意,一旦你修复了它,就回到可选链。)

很多人对隐式展开的可选值很苛刻,但在某些时候和地方它们可以派上用场。我想说这是其中之一——你需要通过的可选链是你可以在应用程序构建时(而不是在源代码编译时)确保的东西,因为它是你的应用程序中附带的 DAE 的配置。 (这与 IBOutlet 通常是 IUO 的基本原理相同。)写 ship.geometry!.firstMaterial!.contents 会提醒您 DAE 所拥有的与您认为的不匹配,因为您会崩溃取消引用 geometry