GameplayKit Integration
SKTiled supports Apple’s GameplayKit by allowing users to build pathfinding graphs in tile layers (currently only orthogonal tile layers are supported). Every SKTileLayer
instance has an optional GKGridGraph
attribute accessible via the SKTileLayer.graph
attribute.
Building Graphs
You can create navigation graphs in tile layers by using the layer’s SKTileLayer.initializeGraph
method. To do so, you’ll need to specify which tiles you intend to be walkable, and are not.
You can automatically flag tiles as walkable/obstacle by adding a custom property to a tileset tile id in Tiled.
// gather walkable & obstacles
let walkable = graphLayer.getTiles().filter { $0.tileData.walkable == true }
let obstacles = graphLayer.getTiles().filter { $0.tileData.obstacle == true }
// initialize the graph for the layer
let graph = graphLayer.initializeGraph(walkable: walkable, obstacles: obstacles, diagonalsAllowed: false)!
Any tile matching those ids will be assigned a graph node.
You can also initialize a layer’s graph with an array of walkable IDs:
let pathsLayer = tilemap.tileLayers(named: "Paths").first!
let walkable: [Int] = [12, 13, 14, 42, 43, 44]
let graph = graphLayer.initializeGraph(walkableIDs: walkable, obstacleIDs, [], diagonalsAllowed: false)!
Navigation Key
If your SpriteKit scene is subclassed from SKTiledScene
, navigation graphs will automatically be added to the SKTiledScene.graphs
dictionary on creation. Each graph is accessible with a key, which defaults to the name of the parent tile layer. To customize the key value, add a custom property to the tile layer named “navigationKey”.
Custom Graph Nodes
SKTiled allows you to deploy your own GKGridGraphNode
node types for use in pathfinding graphs. If you implement the SKTilemapDelegate
protocol, you can override the SKTilemapDelegate.objectForGraphType
function to return your custom GKGridGraphNode
type.
Graph Node Weight
The included SKTiledGraphNode
class adds a weight
attribute that can be used to affect the outcome of heuristic pathfinding.
let coord = CGPoint(x: 10, y: 8)
if let node = tileLayer.graph.node(atGridPosition: coord) as? SKTiledGraphNode {
node.weight = 100.0
}
You can also pass the value through a property in Tiled with a float attribute weight
:
Debugging the Graph
To see a visual representation of any layer’s navigation graph, use the SKTileLayer.debugDrawOptions
property.
graphLayer.debugDrawOptions = .drawGraph
See the debugging page for more information.
Next: Extending SKTiled - Index