Class

SKFieldNode

A node that applies physics effects to a portion of the scene.

Overview

There are many different kinds of field nodes that can be created, each with different effects. The Creating Field Nodes section lists the field types you can create using SpriteKit, including a type that allows you to apply custom forces to physics bodies. Instantiate the appropriate kind of field node and then add it to the scene’s node tree.

When the scene simulates physics effects, a field node applies its effect to a physics body so long as the following things are true:

  • The field node is in the scene’s node tree.

  • The field node’s isEnabled property is true.

  • The physics body is attached to a node that is in the scene’s node tree.

  • The physics body is located inside the field node’s region (see region).

  • The physics body is not located inside the region of another field node whose isExclusive property is set to true.

  • A logical AND operation between the field node’s categoryBitMask property and the physics body’s fieldBitMask property results in a nonzero value.

Adding Physics Fields to Your Scene

It is possible to implement a game using only physics bodies, collisions, and applied forces, but sometimes this can be a lot of work. For example, if you wanted two objects to be attracted to each other, you would have to perform gravity calculations and apply those forces every time a new frame is calculated. When you want to apply generalized effects to a scene, you can do this easier using physics fields.

A physics field is a node that is placed inside your scene’s node tree. When the scene simulates physics, the physics field affects physics bodies that are configured to interact with it. There are many different kinds of fields effects, all of which are defined in Creating Field Nodes.

Listing 1 shows one of these fields, a linear gravity field. In this example, a field node replaces the default gravity provided by the scene’s physics world. First, the scene's default gravity is disabled. Then, the scene creates a linear gravity field with a vector pointing towards the bottom of the screen and gives the node a strength equal to Earth’s gravity. Finally, it adds the node to itself.

physicsWorld.gravity = CGVector(dx:0, dy: 0);

let gravityVector = vector_float3(0,-1,0);

let gravityNode = SKFieldNode.linearGravityField(withVector: gravityVector)

gravityNode.strength = 9.8

addChild(gravityNode)

Here are some reasons you might use a field node rather than the default gravity:

  • You can vary the strength and direction of gravity independently of each other.

  • You can vary the strength of the field using actions.

  • You can change the direction of gravity by rotating the field node.

gravityNode.zRotation = CGFloat.pi // Flip gravity.

  • You can enable and disable gravity using the field node’s isEnabled property, without changing the field node’s strength or direction.

Limiting the Effect of Field Nodes through Categories and Regions

By default, a field node affects all physics bodies in the scene. However, it doesn’t have to be this way. By carefully controlling which physics bodies are affected by a field node, you can create some interesting effects.

Field nodes are categorized just like physics bodies. Similarly, physics bodies declare which field categories affect them. Combining these two properties, you can decide which kinds of fields are implemented by your game and which physics bodies are affected by each of those fields. Typically, you do this by using the field categories to define general effects that you can drop into a game. For example, assume for the moment that you are implementing a game where you want to add gravity to a planet. Gravity should pull objects such as ships and asteroids towards the planet. The following code creates a category for gravity effects. When a planet is created, a separate radial gravity field node is added to it as a child, and is configured to use the gravity category. Whenever a new physics body is created, the body’s mask is configured to determine which fields should affect it. Ships are affected by gravity, and missiles are affected by force fields.

let gravityCategory: UInt32 = 0x1 << 0
let shieldCategory: UInt32 = 0x1 << 1
...
let gravity = SKFieldNode.radialGravityField()
gravity.strength = 3
gravity.categoryBitMask = gravityCategory
planet.addChild(gravity)
...
ship.physicsBody?.fieldBitMask = gravityCategory
...
missile.physicsBody?.fieldBitMask = shieldCategory

So, time to implement that force field: a shield object that will deflect incoming missiles. One interesting way to do this is with another radial gravity field, but using a negative field strength: physics bodies are repelled away from the ship. But a field that affects the whole scene might be more than you want; instead the field should only affect nearby missiles. You define the area that a field effects using two properties on the field node object.

  • A field node’s region property determines the area where the field can affect things. By default, this region covers the entire scene. However, you can choose to give the region a finite shape instead. For the forcefield, a circular area is fine, but other shapes are possible. You can even construct them using constructive set geometry (CSG).

  • A field node’s falloff property determines how fast the field loses its strength. You can choose to have the field not lose strength at all or you can choose to have it fall off more quickly than the default. For a radial gravity field, the default is to have it drop off based on the square of the distance to the other body’s center. Not all field types are affected by the falloff property.

The following code adds a temporary force field to the rocket ship. The field node is created and configured to repel missiles. Then a circular region is added to limit the area affected by the node and the field is configured so that its strength drops off more quickly as a function of distance. Finally, the field should weaken and disappear so that the ship is not invulnerable. The field is weakened using an action that first animates a drop in strength to nothing, and then removes the shield node. In an actual game, the shield effect might be embellished with a graphical effect rendered on top of the ship.

let shield = SKFieldNode.radialGravityField()
shield.strength = -5
shield.categoryBitMask = shieldCategory
shield.region = SKRegion(radius: 100)
shield.falloff = 4
shield.run(SKAction.sequence([
    SKAction.strength(to: 0, duration: 2.0),
    SKAction.removeFromParent()
    ]))
ship.addChild(shield)

Topics

Creating Field Nodes

class func dragField()

Creates a field node that applies a force that resists the motion of physics bodies.

class func electricField()

Creates a field node that applies an electrical force proportional to the electrical charge of physics bodies.

class func linearGravityField(withVector: vector_float3)

Creates a field node that accelerates physics bodies in a specific direction.

class func magneticField()

Creates a field node that applies a magnetic force based on the velocity and electrical charge of the physics bodies.

class func noiseField(withSmoothness: CGFloat, animationSpeed: CGFloat)

Creates a field node that applies a randomized acceleration to physics bodies.

class func radialGravityField()

Creates a field node that accelerates physics bodies toward the field node.

class func springField()

Creates a field node that applies a spring-like force that pulls physics bodies toward the field node.

class func turbulenceField(withSmoothness: CGFloat, animationSpeed: CGFloat)

Creates a field node that applies a randomized acceleration to physics bodies.

class func velocityField(with: SKTexture)

Creates a field node that sets the velocity of physics bodies that enter the node’s area based on the pixel values of a texture.

class func velocityField(withVector: vector_float3)

Creates a field node that gives physics bodies a constant velocity.

class func vortexField()

Creates a field node that applies a perpendicular force to physics bodies.

class func customField(evaluationBlock: SKFieldForceEvaluator)

Creates a field node that calculates and applies a custom force to the physics body.

Determining Which Physics Bodies Are Affected by the Field

var isEnabled: Bool

A Boolean value that indicates whether the field is active.

var isExclusive: Bool

A Boolean value that indicates whether the field node should override all other field nodes that might otherwise affect physics bodies.

var region: SKRegion?

The area (relative to the node’s origin) that the field affects.

var minimumRadius: Float

The minimum value for distance-based effects.

var categoryBitMask: UInt32

A mask that defines which categories this field belongs to.

Configuring the Strength of the Field

var strength: Float

The strength of the field.

var falloff: Float

The exponent that defines the rate of decay for the strength of the field as the distance increases between the node and the physics body being affected.

Configuring Other Field Properties

These properties are associated with specific types of field nodes.

var animationSpeed: Float

The rate at which a noise or turbulence field node changes.

var smoothness: Float

The smoothness of the noise used to generate the forces.

var direction: vector_float3

The direction of a velocity field node.

var texture: SKTexture?

A normal texture that specifies the velocities at different points in a velocity field node.

Constants

typealias SKFieldForceEvaluator

The definition for a custom block that processes a single physics body’s interaction with the field.

Relationships

Inherits From

See Also

Simulating Physics

class SKPhysicsWorld

An object which encapsulates a scene's physics simulation.

class SKPhysicsBody

An object which adds physics simulation to a node.

class SKPhysicsContact

A description of the contact between two physics bodies.

protocol SKPhysicsContactDelegate

Methods your app can implement to respond when physics bodies come into contact.

class SKPhysicsJoint

The abstract superclass for objects that connect physics bodies.

class SKPhysicsJointFixed

A joint that fixes two physics bodies together.

class SKPhysicsJointLimit

A joint that imposes a maximum distance between two physics bodies, as if they were connected by a rope.

class SKPhysicsJointPin

A joint that pins together two physics bodies, allowing independent rotation.

class SKPhysicsJointSliding

A joint that allows two physics bodies to slide along an axis.

class SKPhysicsJointSpring

A joint that simulates a spring connecting two physics bodies.

class SKRegion

A definition of an arbitrary area.