【Swift】SpriteKitの使い方。シーンを重ねて表示する。(Swift 2.2、XCode 7.3)

2020年6月16日

SKReferenceNodeとは

本記事ではSpriteKit Sceneファイルの編集画面(シーンエディタ)の部品一覧にあるSKReferenceNode(以下、参照ノード)について説明する。

Reference

 

参照ノードとは、SpriteKit Sceneファイル(以下、SKSファイル)やパーティクルファイルなどを参照して、シーンに配置するノードである。これを使えば、シーンの中に別のシーンを重ねて表示するようなことができる。

 

参照ノードを使ってみる

実際に参照ノードを使って、2つのシーンを重ねて表示してみよう。以降の手順を行う前のXcodeプロジェクトをGitHubに置いたので、試してみる方はご利用下さい。⇒「テスト用プロジェクト

事前準備で2つのシーンを作成しておいた。

1つ目のシーン(以下、シーン1)は、背景と猿とスピーカーのノードを配置し、ドラッグ&ドロップで猿を運べるようにした。

シーン1、猿とスピーカーのノード

 

2つ目のシーン(以下、シーン2)は、2匹の鶏のノードを配置し、左右に自動で往復するようにしておいた。

2匹の鶏のノードを配置

 

これから、参照ノードを利用してシーン1にシーン2を重ねて表示させる。

下図赤枠のSKSファイルを選択してシーンエディタを開く。黄緑枠のオブジェクトライブラリボタンを押して部品一覧を表示し、ドラッグ&ドロップで「Reference」をシーンに配置する(紫矢印)。

黄枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Nameに「referenceNode」、Referenceに「TestScene2.sks」、PositionにX「0」、Y「0」を入力する。

PositionにX「0」、Y「0」を入力した理由は、参照ノードの座標がアンカーポイントになってノードが配置されるためである。なので仮に、シーン2のアンカーポイントが別の座標だったら、参照ノードもその座標に合わせることになる。

SKReferenceNodeをシーンに追加する

 

以下は実際のプレイ動画。2つのシーンが重なって表示された。

ちなみに、ソースコードで参照ノードを追加するときはdidMoveToViewメソッドを以下のコードのようにする。

 

ちなみに、参照ノードを作成するときにファイル名を指定するとエラーが発生する(Swift 2.2、XCode 7.3)

Terminating app due to uncaught exception 'Cant add body, already exists in a world’, reason: 'Cant add body type: representedObject:[ name:'(null)’ frame:{{-0, -0}, {320, 568}} anchor:{0, 0}], already exists in a world’

 

参照先のノードを取得する

通常はシーンに配置したノードを取得するときは、ノード名を引数に以下のメソッドを呼び出して取得してきた。

 

しかし、上記だとシーンの子ノードしか検索対象になってないので、孫ノードや、参照ノードが配置したノードが検索できない。

孫ノードや、参照ノードが配置したノードも検索対象に含めたい場合は、検索文字列の先頭に「//」をつけてノードツリー全体を検索対象にする。

 

検索文字列にはワイルドカードを含めることができる。例えば、ノードツリー全体を検索対象とし、かつ、「m」から始まるノードを検索する場合は以下のコードになる。

 

以下のコードは先頭が「m」、2文字目が「o、p、q」のノードが抽出される。

 

階層を指定した検索もできる。検索文字列の記述方法について詳しくは公式リファレンスを参照されたし。
⇒公式リファレンス「SKNode

 

上記を踏まえて、スピーカーがタップされたら鶏ノードを消すには、TestScene.swiftのtouchesBeganメソッドを以下のコードに変更する。

 

以下は実際のプレイ動画。鶏が1匹消えた。

 

childNodeWithNameメソッドで取得できるノードは1つだけである。たとえ検索文字列にマッチするノードが複数あったとしても、最初に見つかったノードのみ取得される。

鶏を全部消したいときは、以下のコードのようにenumerateChildNodesWithNameメソッドを利用する。

 

以下は実際のプレイ動画。スピーカーをタップしたら鶏が全部消えた。