Apple Engine

Apple, iPhone, iOS, その周辺のことについて

WWDC 2017 の SceneKit サンプル Fox 2 を調べる その9

Swift ファイルが保存されているフォルダ

Shared には全体で共有する Swift ファイルがあり、
iOS、tvOS、macOS ではプラットフォーム別で AppDelegate.swift と Main.storyboard から呼ばれる GameViewController.swift で構成されている

iOS 版のみ、ヴァーチャルキーボードを使用するため 3つ Swift ファイルが追加されている。

 

Swift ファイルについて

Shared と 各プラットフォームのフォルダmのファイルをざっくり見てゆく。

 

Shared

以下の Swift ファイルがある

  • Character.swift
  • GameController.swift
  • Overlay.swift
  • BaseComponent.swift
  • ChaserComponent.swift
  • PlayerComponent.swift
  • ScaredComponent.swift
  • SimdExtensions.swift
  • UI フォルダ内の Button.swift、Slider.swift、Menu.swift

 

Character.swift

基本的にはプレイヤーキャラ Max 自体の振る舞い設定を全てここで決めており、 GameController.swift でこちらの設定を使用し Max を動かしている。

 

GameController.swift

シーン全体設定する NSObject のクラス。
各プラットフォームの GameViewController の UIViewController でこのクラスをイニシャライズし、その際に各 Main.storyboard で設定されている SCNView 渡して共通の処理をしている。

 

Overlay.swift

右上のアイコン類、クリア時のロゴと Max の 2D 画像を画面の UI を SpriteKit の SKScene で設定しており、GameController.swift で SceneKit の overlaySKScene でこちらを設定している。

iOS のヴァーチャルパッドは iOS フォルダの Swift ファイルで設定している。

 

BaseComponent.swift

GameplayKit の GKComponent を継承したクラスで、敵キャラなどの動作の元となる設定がされている。
目標に沿って動作するエージェントシステムが使用できる GKAgent2D を効率よく使用するため、GKComponent を使用している。
また、このファイルで GKAgent2D の Extension を作成している。

GKAgent2D の他に GKAgent3D があるが、今回は Y 座標に対して、追跡を行わないため 3D の方は使用していない模様。

 

PlayerComponent.swift

BaseComponent を継承したクラスで、Character.swift でキャラ設定しているクラスを GKComponent で取得している。

ChaserComponent.swift と ScaredComponent.swift ではこちらのクラスからキャラ設定を取得して、近づいたり、離れたりするための位置情報取得と、攻撃の状態を調べているために使用している。

 

ChaserComponent.swift
ScaredComponent.swift

近づく敵や遠ざかる敵の設定。
基本的にはほぼ同じで GKAgent2D 目的地となる複数の GKGoal を設定したり、 敵キャラの状態の設定や状態ごとの振る舞いを決めている。

状態の判別は GameplayKit の State Machine は使用せず、enum の設定から調べている。

 

SimdExtensions.swift

SIMD で設定している行列の処理を簡単にする Extension。
基本的には simd_float2、3、4 での == や != のオペレーターや、 simd_float4x4 で 位置情報 xyz 代入したり取得する関数が追加されている。

ちなみに、Fox 2 座標変換はほぼ iOS11 などで追加された SIMD で計算されている。

 

UI フォルダ内の Button.swift、Slider.swift、Menu.swift

デバッグ用の UI と機能があり、Button.swift ボタンに関する UI。 Slider.swift スライダーの UI。Menu.swift はこれらを表示するものとなっており、Overlay.swift 内で設定されている。
ボタンはカメラの切り替え、スライダは被写界深度の調整を行う。

左上の Max の画像をタップすると出現するはずだが、設定している座標の問題でボタンが表示されず、スライダーは IBAction の設定されていないため使用できない。

 

iOS

以下の Swift ファイルがある

  • ButtonOverlay.swift
  • PadOverlay.swift
  • ControlOverlay.swift
  • GameViewController.swift
  • AppDelegate.swift

 

ButtonOverlay.swift

ヴァーチャルパッドで使用する A、B ボタンの SKNode とタッチイベントを設定している。
GameController.swift でメソッドを実行できる用に ButtonOverlayDelegate が設定されている。

 

PadOverlay.swift

ヴァーチャルパッドで使用するパッドの SKNode とタッチイベントを設定している。
GameController.swift でメソッドを実行できる用に PadOverlayDelegate が設定されている。

 

ControlOverlay.swift

ヴァーチャルパッドの部品であるパッド2つとボタン2つを配置している SKNode。

Overlay.swift 内で「#if os( iOS ) ... #endif」を使用し、iOS の場合のみこちらを表示し動作するようにしている。

 

GameViewController.swift

起点となる UIViewController。 Main.storyboard で view に SCNView が設定されている。

Shared フォルダ GameController の呼び出し時に、この view である SCNView を渡している。

また、iPad の場合は UIView の contentScaleFactor を調べ 1.3 より大きい場合は 1.3 に変更し、preferredFramesPerSecond を 60 にしている。

 

AppDelegate.swift

通常の AppDelegate.swift。

 

tvOS

GameViewController.swift

起点となる UIViewController。 Main.storyboard で view に SCNView が設定されている。

Shared フォルダ GameController の呼び出し時に、この view である SCNView を渡している。

 

AppDelegate.swift

通常の AppDelegate.swift。

 

macOS

GameViewController.swift

通常の macOS アプリ同様に NSWindow の 起点となる NSViewController。 Main.storyboard の view ではカスタムクラスの GameViewMacOS が呼ばれており SCNView が継承され設定されている。

Shared フォルダ GameController の呼び出し時に、この view である SCNView を渡している。

 

NSViewController では iOS のヴァーチャルパッドと同様の振る舞いを keyUp, keyDown のキーボード操作に該当する関数で設定している。

カスタムクラスの GameViewMacOS は、ウィンドウのサイズ変更時に Overlay.swift の layout2DOverlay() で UI 領域を再描画したり、viewDidMoveToWindow で NSViewController へサブビューとしてこちらが追加された際に contentsScale を 1 にして Retina 表示ではなくしている。

また、NSViewController ではキーボードイベントがないため、この View のキーイベントを NSViewController の関数にアクセスしている。

 

AppDelegate.swift

通常の AppDelegate.swift。

 

以上、ざっくりと Fox 2 のプロジェクトで使用している Swift ファイルの説明をしてみた。

次回、コードの深掘りの前に GameplayKit 概要を見てゆく。