sdd
sdd

Reputation: 877

Value of optional type CGFloat? not unwrapped, did you mean to use ! or?

There is a impulse applied to a ball. but this ball keeps moving after that impulse, but I want it to move just a bit. So here is what I am trying:

var impulse:CGFloat = 0.22 // bal impulse

applying impulse:

bal.physicsBody?.applyImpulse(CGVectorMake(50 * impulse, 50 * impulse))

trying to limit the movement:

  if bal.physicsBody?.velocity.dx > impulse{
        bal.physicsBody?.velocity.dx = bal.physicsBody?.velocity.dx - impulse
    }

But this last piece of code is getting this error:

Value of optional type CGFloat? not unwrapped, did you mean to use ! or ?

How to fix?

Upvotes: 2

Views: 2453

Answers (2)

Airspeed Velocity
Airspeed Velocity

Reputation: 40965

Given you’ve asked a similar question recently, you really need to spend some time understanding optionals, as you’ll keep hitting these kind of problems. You need to get a feel for what optionals are, and what the different techniques are for handling them. Try reading this and this to start.

In this particular example, you have an optional velocity, because you are accessing it via another optional, physicsBody, via “optional chaining” (?.). So to perform an operation like - on it, you need to use an optional technique. This looks like a good case for a if let with an extra where clause:

if let v = bal.physicsBody?.velocity where v.dx > impulse {
    bal.physicsBody?.velocity = CGVector(dx: v.dx - impulse, dy: v.dy)
}

Note, optional chaining can be “assigned through” which is why bal.physicsBody?.velocity = works.

Also, there’s no need to use CGVectorMake. Unlike in Objective-C, CGVector has an initializer that takes the same parameters (as shown above).

Upvotes: 2

Dejan Skledar
Dejan Skledar

Reputation: 11435

When workking with optionals, you always should unwrap them using if let, because if you use the ? and the value is nil, the code will not execute, and you will not know that there was a nil value.

Use it like this:

var impulse:CGFloat = 0.22 // bal impulse

if let body = bal.physicsBody {

     body.applyImpulse(CGVectorMake(50 * impulse, 50 * impulse))

     if body.velocity.dx > impulse {
          body.velocity.dx = body.velocity.dx - impulse
     }
}
else
{
   // bal.physicsBody is nil !
}

Upvotes: 2

Related Questions