Unexpectedly Found Nil SKSpriteNode

旧巷老猫 提交于 2019-12-13 02:22:12

问题


I get the following error when there's contact between bullet and the plane.

fatal error: unexpectedly found nil while unwrapping an Optional value

Plane Function:

func addPlane() {
    var myplane : SKSpriteNode?
    myplane = SKSpriteNode(imageNamed: "plane")
    let actualY = random(min: 100, max: size.height - myplane!.size.height/2)
    myplane!.position = CGPoint(x: size.width + myplane!.size.width/2, y: actualY)
    myplane!.physicsBody = SKPhysicsBody(rectangleOfSize: myplane!.size) // 1
    myplane!.physicsBody?.dynamic = false // 2
    myplane!.physicsBody!.categoryBitMask = CollisionCategoryPowerUpOrbs
    myplane!.physicsBody!.collisionBitMask = 0
    myplane!.name = "plan"
    addChild(myplane!)//
    let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))
    let actionMove = SKAction.moveTo(CGPoint(x: -myplane!.size.width/2, y: actualY), duration: NSTimeInterval(actualDuration))
    myplane!.runAction(SKAction.sequence([actionMove]))

}

When the user touches the screen, it will shoot a bullet with this funciton:

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        guard let touch = touches.first else {
            return
        }
        let touchLocation = touch.locationInNode(self)
        var projectile : SKSpriteNode?
        projectile = SKSpriteNode(imageNamed: "bomb")
        projectile!.position = CGPoint(x: 50, y: 100.0)
        projectile!.physicsBody = SKPhysicsBody(circleOfRadius: projectile!.size.width/2)
        projectile!.physicsBody?.dynamic = true
        projectile!.physicsBody!.allowsRotation = false
        projectile!.physicsBody!.categoryBitMask = CollisionCategoryPlayer
        projectile!.physicsBody!.contactTestBitMask = CollisionCategoryPowerUpOrbs
        projectile!.physicsBody!.collisionBitMask = 0
        projectile!.physicsBody!.linearDamping = 1.0
        projectile!.name = "shot"
        let offset = touchLocation - projectile!.position
        if (offset.x < 0) { return }
        addChild(projectile!)
        let direction = offset.normalized()
        let shootAmount = direction * 1000
        let realDest = shootAmount + projectile!.position
        let actionMove = SKAction.moveTo(realDest, duration: 2.0)
        let actionMoveDone = SKAction.removeFromParent()
        projectile!.runAction(SKAction.sequence([actionMove, actionMoveDone]))
}

Function to hide the plane on contact:

func didBeginContact(contact: SKPhysicsContact) {
    let nodeB = contact.bodyA.node!
    if nodeB.name == "plan" {
        nodeB.removeFromParent()
    }
}

I call the addPlane function in ViewDidLoad like this:

runAction(SKAction.repeatActionForever(
    SKAction.sequence([
        SKAction.runBlock(addPlane),
        SKAction.waitForDuration(1.5)
    ])
))

回答1:


Change you code with a '?' to do a nil check:

func didBeginContact(contact: SKPhysicsContact) {

  let nodeB = contact.bodyA.node
  if nodeB?.name == "plan" {     
    nodeB?.removeFromParent()
  }
}

This solution will prevent the crash but has the disadvantage that some unnecessary contact events are still triggered.

Removing a node inside didBeginContact should be avoided. This can lead to situations where the node is already removed (nil), but the PhysicsBody is still active. (see also the comments from KnightOfDragon)



来源:https://stackoverflow.com/questions/36655903/unexpectedly-found-nil-skspritenode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!