找到你要的答案

Q:Hit fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)

Q:击中致命错误:意外发现零而展开的一个可选值(LLDB)

I programming a simple game and at the first collision I get the following error:

Hit fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)

Here's my code:

func didBeginContact(contact: SKPhysicsContact) {

    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB

    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
        (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {
            projectileDidCollideWithMonster(firstBody.node as SKSpriteNode, monster: secondBody.node as SKSpriteNode)

    }

}

我编程一个简单的游戏,在第一次碰撞,我得到以下错误:

击中致命错误:意外发现零而展开的一个可选值(LLDB)

这是我的密码:

func didBeginContact(contact: SKPhysicsContact) {

    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB

    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
        (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {
            projectiledidcollidewithmonster(firstbody.node SKSpriteNode、怪兽:secondbody.node SKSpriteNode)

    }

}
answer1: 回答1:

Are you using swift 1 or 1.2?

Try

if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
    (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {

    if let firstNode = firstBody.node as? SKSprintNode,
       let secondNode = secondBody.node as? SKSprinteNode {

       projectileDidCollideWithMonster(firstNode, monster: secondNode)
    }
}

你是用雨燕1还是1.2?

尝试

if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
    (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {

    if let firstNode = firstBody.node as? SKSprintNode,
       let secondNode = secondBody.node as? SKSprinteNode {

       projectileDidCollideWithMonster(firstNode, monster: secondNode)
    }
}
answer2: 回答2:

I had the same problem before, this is what I did

Basically, when you're unwrapping the physics body (this usually happens at the line that says secondBody.node!) the following happens:

  1. If you have 3 bodies (a, b, c) that collide, and collision logic applies to all 3, sprite kit will perform 2 collision checks:

    • One with bodies a and b
    • then with bodies b and c
  2. you are removing bodies on collision:

    • first detection : bodies a and b are unwrapped, bodies a and b are removed

    • second detection : only body c is left because a and b were removed. This means secondBody or firstBody is now nil. So the error is thrown

Try changing your code to the following, and it should fix the issue:

var firstBody: SKPhysicsBody?
var secondBody: SKPhysicsBody?

if (firstBody!.node! != nil && secondBody!.node! != nil) {
       if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
                (secondBody.categoryBitMask & PhysicsCategory.Projectile != 0)) {
                projectileDidCollideWithMonster(secondBody.node!, monster: firstBody.node!)
        }
}

我以前也有过同样的问题,这就是我所做的

基本上,当你展开物理身体(这通常发生在线说secondbody。结!)以下发生:

  1. 如果你有3个身体(A,B,C)碰撞,碰撞逻辑适用于所有3个,雪碧套件将执行2碰撞检查:

    • One with bodies a and b
    • then with bodies b and c
  2. 你在碰撞中移除物体:

    • 第一次检测:体A和B是打开的,体A和B被移除

    • 第二个检测:只有身体C离开,因为A和B被删除。这意味着secondbody或firstbody现在是零。所以抛出错误

尝试 changing your code to the following, and it should fix the issue:

var firstBody: SKPhysicsBody?
var secondBody: SKPhysicsBody?

if (firstBody!.node! != nil && secondBody!.node! != nil) {
       if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
                (secondBody.categoryBitMask & PhysicsCategory.Projectile != 0)) {
                projectileDidCollideWithMonster(secondBody.node!, monster: firstBody.node!)
        }
}
answer3: 回答3:

Try this way:

if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
    (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {
    if(firstBody.node != nil && secondBody.node != nil ) {
        projectileDidCollideWithMonster(firstBody.node as SKSpriteNode, monster: secondBody.node as SKSpriteNode) }
}

尝试 this way:

if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
    (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {
    if(firstBody.node != nil && secondBody.node != nil ) {
        projectiledidcollidewithmonster(firstbody.node SKSpriteNode、怪兽:secondbody.node SKSpriteNode) }
}
answer4: 回答4:

Ok this took me a while to figure out but I got it in the end. I tried most of the other solutions I could find online with very little luck. I had to figure it out the hard way. What you have to do is give the option of a break/ return if a nil is found. Because most of the time this error occurs when two of the same collisions are triggered simultaneously.

what I did is make a if else statement to return the function if a nil occurs.

func didBeginContact(contact: SKPhysicsContact) {

var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody

if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
    firstBody = contact.bodyA
    secondBody = contact.bodyB

} else {
    firstBody = contact.bodyB
    secondBody = contact.bodyA
}

if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
    (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {
// new part
    if (firstBody.node == nil || secondBody.node == nil)
    {return}

else {
 projectileDidCollideWithMonster(firstBody.node as SKSpriteNode, monster: secondBody.node as SKSpriteNode)
}}}

I hope this helps. It is also important that you treat it like you are expecting a nil by having the return statement in the if and not the else.

好吧,这花了我一段时间来揣摩,但我得到了它的结束。我尝试了大多数其他的解决方案,我可以找到网上很少运气。我不得不用艰难的方式。你所要做的是给一个休息/返回选项,如果发现一个零。因为大多数时候,当两个相同的碰撞同时触发时,会发生此错误。

我做的是做一个if语句来返回函数,如果一个零发生。

func didBeginContact(contact: SKPhysicsContact) {

var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody

if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
    firstBody = contact.bodyA
    secondBody = contact.bodyB

} else {
    firstBody = contact.bodyB
    secondBody = contact.bodyA
}

if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
    (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {
// new part
    if (firstBody.node == nil || secondBody.node == nil)
    {return}

else {
 projectiledidcollidewithmonster(firstbody.node SKSpriteNode、怪兽:secondbody.node SKSpriteNode)
}}}

I hope this helps. It is also important that you treat it like you are expecting a nil by having the return statement in the if and not the else.

swift  sprite-kit