SpriteKit and Inverse Kinematics with Swift
- Getting Started
- Overview of Skeletal Hierarchy
- Setting up a Rest Pose
- What Is Inverse Kinematics?
- Forward Kinematics
- Inverse Kinematics
- Inverse Kinematics Actions
- Defining an Inverse Kinematics Action
- Setting Up an End-Effector
- Defining Joint Constraints
- Creating a Punching Motion
- Punching With Both Fists
- Facing the Target
- Head Tracking
- Hitting Moving Targets
- Creating a Kicking Motion
- Finishing Touches
- Gratuitous Background Music
- Where to Go From Here?
If you’ve ever added an animated character to a game, you probably pre-created animations for running, punching, jumping and so forth, and played them when the game executes the associated actions.
While this “canned” approach works for simple scenarios, there are often cases where you’d prefer your character to interact more realistically with other game objects.
For instance, if your character needs to reach out to pick up a nearby object at a variable height, you may not want to use the same animation for every picking action, or it could look really silly when the predefined hand motions don’t line up exactly with the object’s position!
Since iOS 8, Sprite Kit comes with inverse kinematics, a technique that alleviates this issue by allowing you to procedurally generate joint motions such as reaching out to a point in space. This means you don’t have to resort to making a possibly infinite number of animations to reach every possible position.
In this tutorial, you’ll learn how to use Sprite Kit’s inverse kinematics feature to implement dynamic punches and kicks in a fun and simple ninja game. :]
In particular, you’ll learn how to:
- Set up joint hierarchies in the Sprite Kit Scene Editor.
- Define joint constraints for more realistic joint behavior.
- Dynamically animate selected joint hierarchies such that the terminal bones can reach out to various positions in 2D space.
Let’s get moving!
Note: This Swift tutorial assumes you have working knowledge of Sprite Kit and Swift. If you’re new to Sprite Kit, check out our Sprite Kit Swift Tutorial for Beginners or our full book, 2D Apple Games by Tutorials. For an introduction to Swift, check out this beginner Swift tutorial.
Download the starter project, open it in Xcode and build and run it. You’ll see a static ninja already set up in the middle of the scene, begging to be released from his yoga stretch.
Take some time to familiarize yourself with the structure of the sample project. In particular, select GameScene.sks in your project navigator. The file should open up in the integrated Sprite Kit Scene Editor:
Note: Xcode’s Scene Editor provides a convenient user interface for initializing a scene by allowing you to visually manipulate your sprites and their properties such as position, scale and physics bodies. Later, you can create
SKScene objects by unarchiving the .sks files you configured in the Scene Editor.
In the following steps, you’ll take advantage of the Scene Editor to set up and tweak the behavior of the joint hierarchy for your ninja, which would be difficult to visualize and set up programmatically.
Overview of Skeletal Hierarchy
In the scene, you can see that the ninja already has a basic skeleton comprised of a hierarchy of bones, each represented by a sprite node. The nodes are connected in a tree of parent-child relationships, as depicted below:
The lower torso node, in red, is the root parent of the entire skeleton hierarchy, which in turn is a child of the scene itself.
The anchor point for each sprite node acts as a joint connecting the node with its parent. These have been adjusted with an offset so that one end of the node can rotate naturally about the joint.
Setting up a Rest Pose
While the ninja looks cool in that mid-air pose, you unfortunately aren’t building a game involving levitation, so you’ll have to bring him back to earth.
Let’s start by adjusting the legs so they touch the shadow on the ground. In the scene, select the front upper leg node, leg_upper_front, by either clicking on it directly, or selecting it from the scene navigator. After you select it, make sure the Utilities panel is open, displaying the Attributes inspector (the third tab).
Set the rotation of leg_upper_front to -14. You can do this either by rotating the handle of the selected sprite or by setting the Rotation property manually in the editor, as shown below:
Next, select leg_lower_front and set its rotation to -9 to keep it slightly bent backwards.
Moving on to the back leg nodes, set the rotations of leg_upper_back and leg_lower_back to 22 and -30, respectively. You should see the following:
Now that your ninja is finally standing, let’s work on the arms. Set the rotation angles of both upper arm nodes, arm_upper_front and arm_upper_back, to -10. Also, set the rotation angles of the lower arm nodes, arm_lower_front and arm_lower_back, to 130.
You should see the following:
Finally, you’re going to do some housekeeping to ensure that the ninja and the shadow always stays centralized, regardless of the screen size. (Currently, the ninja would be off-center on the iPad 2.)
Switch to GameScene.swift and add the following code within and at the top of the
var shadow: SKNode!
var lowerTorso: SKNode!
didMoveToView(), add the following code:
lowerTorso = childNode(withName: "torso_lower")
lowerTorso.position = CGPoint(x: frame.midX, y: frame.midY - 30)
shadow = childNode(withName: "shadow")
shadow.position = CGPoint(x: frame.midX, y: frame.midY - 100)
Let’s go through what you just did:
- You create two
SKNodeproperties to reference the shadow node and lower torso node (the root node of the ninja), respectively.
- You obtain a reference to the lower torso node by its name, “torso_lower”, and assign its value to the
lowerTorsoproperty. Next, you set its position to the center of the screen with an offset of
- Similarly, you grab a reference to the shadow node by its name, “shadow”, and assign its value to the
shadowproperty. Finally, you set its position to the center of the screen with an offset of
Build and run the project, and you’ll see your ninja in its rest stance, ready for a fight!
With the joint hierarchy all set up and your ninja ready for action, you can begin using Sprite Kit’s inverse kinematics feature to deploy some serious martial arts.