SceneKitを使って実際にアプリをリリースした人はまだあんまりいないだろうなーということで、どんな感じだったかを書いてみようと思います。
SceneKitとは、iOS SDKに含まれている3Dグラフィックのフレームワークです。
モノとしてはUnityと同じアプリケーション層。
球体とかにテクスチャを貼って配置してみたり、光源を置いて影をつけてみたり、空(Skybox)を設定してみたり、重力に合わせて動かしてみたり... と最初に試してみる事としてはUnityと多分変わらないはず。
Metalを使うには iOSの新グラフィックAPI - Metal入門してみる のような処理が必要なのですが、これらを簡単に扱えるようにしたフレームワークです。
では、何でSceneKitを選択してみたか? というと、
- iOSに特化しているから、汎用的に作られているものよりも処理が早いはず
- ブラックボックスが少なくコードでいろいろ書ける方が、(私としては)とっつきやすい
- 直接Metalを扱うほどシビアなものを作ろうとしているわけはない
裏の気持ちとしては、
- どんなものか知りたいという単純な興味
- SceneKitで使える技が他のアプリ開発にも役立つかもしれない(Unityを学ぶよりは)
- Appleさんにフィーチャーしてもらいたい
せっかくなのでSceneKitを使う人のためにあしあとを残してみます。
が、全体は大きすぎるので、今回はSceneKit全体像から。
世界はSCNViewでできている
SceneKitを表示するための大元のViewがSCNViewです。
SCNViewの継承元はUIView。
つまり通常のアプリのUIViewの中に一部として入れることもできちゃいます。
キャラクタの動きなどのアニメーションについても、scnファイルで切り出しします。
これでアニメーションを切り替えることがプログラムから可能になります。
基本構成はscnファイルで
SCNViewにあるSCNSceneが、シーンを管理しているクラス。
SCNSceneは、scnファイルを指定してインスタンスします。
scnファイルは、表示するデータが入ったバイナリファイル。
COLLADA形式の3DモデルをXCodeで変換して作成します。
COLLADAがなくても、簡単なものであればXCodeのエディタで作成できます。
実際には一つのscnファイルで全てのモデルを配置するのではなく、各部品で分けて、組み合わせていく形になるかと思うのですが、この部品もscnファイルで作成します。
scnファイルの中に他のscnファイルの参照を置くことができるし、scnの中のノードをプログラムからアクセスして他のSCNSceneに追加もできます。
実際、Standland でも
scnファイルを組み合わせて、世界全体を作成しています。
キャラクタの動きなどのアニメーションについても、scnファイルで切り出しします。
これでアニメーションを切り替えることがプログラムから可能になります。
イベントの取得はUIViewと同じ
UIGestureRecognizerを登録するとちゃんと反応します。
TouchEvent
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?)
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?)
もちゃんと渡ってきます。
Standlandでは、スワイプ操作でカメラ向きをかえたり、ダブルタップでみんなが一斉にジャンプしていますが、そのイベントの発火元はこれらになっています。
UIViewと同じように扱えるので、すでにアプリ作成を経験している人にとっては良い点ですね。
UIViewと同じように扱えるので、すでにアプリ作成を経験している人にとっては良い点ですね。
SceneKit 内のタップ判定
青いちっこいのがGemmy。
この子をタップするとGemゲットできたりジャンプしたりします。
その時必要になるのが、SCNKit上では、なにがタップされたのか?の判定です。
ここで使用するのは、SCNViewの
func hitTest(point: CGPoint, options: [String : AnyObject]?) -> [SCNHitTestResult]
というメソッド。
これでUITapGestureRecognizerで取得できたPointを使用して、SCNKit上でHitしたオブジェクトが取得できます。
HitしたのがGemmyなのか?うさぎなのか?は、ノードの名前で判断します。
そのため、scnファイルの中で設定しているノード名はちゃんとルールを用意しておきましょう。
2DのOverlayはSpriteKit
例えば、ゲーム終了後にスコアを画面上に2Dで表示したい。
という場合、overlayを設定することができます。
overlayは、SKScene .... つまり、SpritKitフレームワークのオブジェクトを利用します。
SCNSceneRenderer#overlaySKScene
...が、Standlandではoverlayは使わず、UIViewをSCNViewの上に置いちゃっています。
理由としては、Storyboard上でレイアウトをしたかったから。
そして、ボタンなどのハイライトとかUIKitの便利な機能を使いたかったから。
AppleTVにも対応する場合、overlayを使いSceneKit/SpriteKitだけで作成した方が楽かもしれません。
あと、SCNViewをインスタンス中にUIViewで表示、アニメーションとかすると、ビシっと線が入ったりして苦しそうになりますのでご注意を。
という場合、overlayを設定することができます。
overlayは、SKScene .... つまり、SpritKitフレームワークのオブジェクトを利用します。
SCNSceneRenderer#overlaySKScene
...が、Standlandではoverlayは使わず、UIViewをSCNViewの上に置いちゃっています。
理由としては、Storyboard上でレイアウトをしたかったから。
そして、ボタンなどのハイライトとかUIKitの便利な機能を使いたかったから。
AppleTVにも対応する場合、overlayを使いSceneKit/SpriteKitだけで作成した方が楽かもしれません。
あと、SCNViewをインスタンス中にUIViewで表示、アニメーションとかすると、ビシっと線が入ったりして苦しそうになりますのでご注意を。
作成したアプリはこちら↓
Standland - 座りすぎ解消!スタンドランド