Scene Kit Tutorial with Swift Part 3: Physics

In this 5-part Scene Kit tutorial series, you’ll learn how to make your first 3D iOS game: a game like Fruit Ninja called Geometry Fighter! By Chris Language.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 3 of this article. Click here to view the first page.

Working with Forces

Think about objects in real life for a moment: to make something move, such as a spoon on top of a table, you have to apply some sort of physical force on it. Unless you’re living inside the Matrix, your name is Neo, and there isn’t even an actual spoon to begin with. :]

The Scene Kit physics engine does a pretty good job mimicking real-life physics, so just as you’d apply a force to move an object in real life, you’ll need to apply a force on your physics body to move it around.

When you apply a force to a physics body, you use applyForce(_: atPosition: impluse:) and pass in an instance of SCNVector3 for both the force and the position where you want to apply that force, along with whether or not the force will be applied as an impulse. The force that you apply will affect both the linear and angular acceleration of the physics body.

An impulse applies the force only once to the physics body, such as when you kick a ball. Forces that aren’t impulses are applied at each step in the physics simulation. Scene Kit will add up all applied forces on the object and accelerate the physics body according to the net result of those forces. This can simulate something like a booster rocket, where the force is continuous.

Earlier you learned that a force is a vector with an x, y and z component. But what does that mean? Take a look at the diagram below:

ForceVector

A force has both magnitude and direction, so the vector determines the magnitude of the force for each individual axis. In the example above, applying a force with a vector of (x:0, y:10, z:0) moves the body upwards with a vertical force.

To apply a horizontal force, you would only specify the magnitude of the force on the x axis using a vector of (x:10, y:0, z:0). To move the body left instead of right, you would apply a negative magnitude of force on the x axis. When you combine various vectors together like (x:10, y:10, z:0), you can control exactly how you want the body to move – in this case, diagonally.

Forces can also be applied at a specific position on a physics body to produce different movements:

ForceAtLocation

Again, it helps to think of real-life examples. If you had a block in front of you and pushed it, the block would move differently depending on the spot you applied the push. Applying the same force to the left or right of the body’s center of mass, for example, at (x:1, y:0, z:0) would cause it to spin. Applying the force directly in line with the center of mass at (x:0, y:0, z:0) won’t produce a spin.

Applying Forces

Roll up your sleeves – it’s time to apply some force! :]

Add the following code after the line where you create the physics body for geometryNode inside spawnShape():

// 1
let randomX = Float.random(min: -2, max: 2)
let randomY = Float.random(min: 10, max: 18)
// 2
let force = SCNVector3(x: randomX, y: randomY , z: 0)
// 3
let position = SCNVector3(x: 0.05, y: 0.05, z: 0.05)
// 4
geometryNode.physicsBody?.applyForce(force, atPosition: position, impulse: true)

Taking each commented line in turn:

  1. This creates two random float values that represent the x- and y-components of the force. It uses an extension on Float from the utilities you added earlier in this chapter.
  2. Next, you use those random components to create a vector to represent this force.
  3. This creates another vector that represents the position the force will be applied to. The position is slightly off-center so as to create a spin on the object.
  4. Finally, using all those components, you apply the force to geometryNode‘s physics body using applyForce(_: atPosition: impluse).

Build and run; as the object spawns out of thin air, some magical force kicks it up into the air instead of dropping like a dead bird:

BuildAndRun1

As gravity takes its toll, the object eventually falls back down.

Working with Torque

Torque is another rotational force you can apply to a body using applyTorque(_: impulse:). Torque only affects the angular momentum of the physics body, not the linear momentum. Applying torque causes an object to spin around its center of mass.

To see how torque affects a physics body, take a look at the following illustration:

TorqueAngles

When applying a torque force, you specify a four-component vector using SCNVector4 rather than a three-component vector as you do with forces. The x-, y- and z-components determine the rotation axis, while the w-component determines the rotation angle, that is, the magnitude of the torque.

Just as you do with applyForce(_: atPosition: impulse:), you can choose whether or not to apply the torque as an impulse, which affect how the physics engine treats the vector.

If the torque is an impulse, the directional vector is treated as an instantaneous change in the angular momentum. Think of spinning a basketball on your finger; to keep the ball spinning, you have to quickly flick the side of the ball with you hand, which applies an a impulse with each flick that instantaneously increases the angular momentum of the ball.

When a torque is not applied as in impulse, it’s applied after each physics simulation step. Scene Kit will sum all applied forces and torques and accelerate the angular force of the physics body according to the net effect of those forces. Think of this as a planet spinning at a constant speed around its own axis.

Note: The Scene Kit physics simulation uses the International System of Units (SI) for measurements: Kilograms for units of mass, Newtons for units of force, Newton-second for units of impulse, and Newton-meter for units of torque.

Adding some Flair

Now that you’ve got your geometric object moving, you may have noticed it spawns out of thin air right in the middle of the screen, which looks a bit awkward. To fix that, you’ll shift the camera on the y-axis a bit so that the object spawns off-screen.

Contributors

Over 300 content creators. Join our team.