squarehippo10 squarehippo10 - 1 year ago 107
iOS Question

SpriteKit reference nodes from level editor

I'm using the scene editor in SpriteKit to place color sprites and assign them textures using the Attributes Inspector. My problem is trying to figure out how to reference those sprites from my GameScene file. For example, I'd like to know when a sprite is a certain distance from my main character.

Edit - code added

I'm adding the code because for some reason, appzYourLife's answer worked great in a simple test project, but not in my code. I was able to use Ron Myschuk's answer which I also included in the code below for reference. (Though, as I look at it now I think the array of tuples was overkill on my part.) As you can see, I have a Satellite class with some simple animations. There's a LevelManager class that replaces the nodes from the scene editor with the correct objects. And finally, everything gets added to the world node in GameScene.swift.

Satellite Class

func spawn(parentNode:SKNode, position: CGPoint, size: CGSize = CGSize(width: 50, height: 50)) {
self.size = size
self.position = position
self.name = "satellite"
self.physicsBody = SKPhysicsBody(circleOfRadius: size.width / 2)
self.physicsBody?.affectedByGravity = false
self.physicsBody?.categoryBitMask = PhysicsCategory.satellite.rawValue
self.physicsBody?.contactTestBitMask = PhysicsCategory.laser.rawValue
self.physicsBody?.collisionBitMask = 0

func createAnimations() {
let flyFrames:[SKTexture] = [textureAtlas.textureNamed("sat1.png"),
let flyAction = SKAction.animateWithTextures(flyFrames, timePerFrame: 0.14)
satAnimation = SKAction.repeatActionForever(flyAction)

let warningFrames:[SKTexture] = [textureAtlas.textureNamed("sat8.png"),
let warningAction = SKAction.animateWithTextures(warningFrames, timePerFrame: 0.14)
warningAnimation = SKAction.repeatActionForever(warningAction)

func warning() {

Level Manager Class

import SpriteKit

class LevelManager
let levelNames:[String] = ["Level1"]
var levels:[SKNode] = []

for levelFileName in levelNames {
let level = SKNode()
if let levelScene = SKScene(fileNamed: levelFileName) {
for node in levelScene.children {
switch node.name! {
case "satellite":
let satellite = Satellite()
satellite.spawn(level, position: node.position)
default: print("Name error: \(node.name)")

func addLevelsToWorld(world: SKNode)
for index in 0...levels.count - 1 {
levels[index].position = CGPoint(x: -2000, y: index * 1000)

GameScene.swift - didMoveToView

world = SKNode()
world.name = "world"

physicsWorld.contactDelegate = self

levelManager.levels[0].position = CGPoint(x:0, y: 0)

//This does not find the satellite nodes
let satellites = children.flatMap { $0 as? Satellite }

//This does work
self.enumerateChildNodesWithName("//*") {
node, stop in
if (node.name == "satellite") {
self.satTuple.0 = node.position
self.satTuple.1 = (node as? SKSpriteNode)!

Answer Source

you will have to loop through the children of the scene and assign them to local objects to use in your code

assuming your objects in your SKS file were named Obstacle1, Obstacle2, Obstacle3

Once in local objects you can check and do whatever you want with them

let obstacle1 = SKSpriteNode()
let obstacle2 = SKSpriteNode()
let obstacle3 = SKSpriteNode()
let obstacle3Location = CGPointZero

func setUpScene() {

    self.enumerateChildNodesWithName("//*") {
        node, stop in

        if (node.name == "Obstacle1") {
            self.obstacle1 = node
        else if (node.name == "Obstacle2") {
            self.obstacle2 = node
        else if (node.name == "Obstacle3") {
            self.obstacle3Location = node.position