16
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

iOSのSceneKitで3D迷路ゲームを作ってみたメモ

Last updated at Posted at 2015-03-13

はじめに

iOSにSceneKitという3Dライブラリがあるのですが、学習がてら、それを利用して簡単なゲームを作ってみました。

ThreeDMaze
https://itunes.apple.com/us/app/threedmaze/id973497184
ソースコード
https://github.com/xylitol45/ThreeDMaze

screen640x640.jpeg

気付いたことをメモってみます。

SCNNode.flattenClone

同じ内容のSNNode(3Dオブジェクト)をあちこちに配置する場合、flattenCloneを利用して、コピーしたSCNNodeを配置すると最適化されてよいらしいです。

SCNCameraのxFov、yFovは角度指定

カメラの画角(広角とか)の指定はSCNCameraxFovyFovを利用します。
ただ、何か理由があるのかもしれませんが、他の回転がほぼラジアン指定なのに対し、ここは角度(0-360)で指定するようになってました。

rotateByAngle:aroundAxis:duration:

SCNActionを利用して、SCNNodeに対し、回転や移動などのアニメーションを設定することができます。
回転の指定は色々あるのですが、今回カメラの回転を行う為に、結局 rotateByAngle:aroundAxis:duration:を使いました。


SCNAction.rotateByAngle(CGFloat(M_PI) * -2, aroundAxis: SCNVector3(x: 1, y: 1, z: 1), duration: 10)

他の回転処理を連続で使うとどうもズレてしまう。。。
(四元数とかジンバルロックとかよく分かってないというのもある)

ただし、このAPIを使うと、現在、アプリの申請時に警告が出るようです。

The app references non-public selectors in Payload/ThreeDMaze.app/ThreeDMaze:rotateByAngle:aroundAxis:duration:

でも、ないはずはないので、これはさっくり無視した感じです(リリースはできた)。

カメラの移動とアニメーション

実機での確認はiPhone6がメインでした。
で、当初、迷路内のオブジェクトにもSCNActionでアニメーション効果をつけていたのですが(迷路内のコインをくるくる回してた)、カメラを回転させると、アプリが落ちまくる。。。
動きの早さはそんなに悪くないんですけどね。
結局、アニメーション効果はあきらめました。

SCNSceneRenderer.overlaySKScene

3D画面へのオーバレイ画面として、SCNSceneRenderer.overlaySKSceneを利用し、SpriteKitのSKSceneを設定することができます。

ただ、SpriteKitの感覚で使ってたら若干挙動が違っていて、

  • SKScene.scaleModeがうまく動いてない?frameは実値で指定したほうがよさげ。
  • 親となるSCNViewで再描画されないと、画面更新されないような。結局、CADisplayLinkを利用する形になりました。
        // CADisplayLinkを利用して、loop処理を作る
        if displayLink == nil {
            displayLink = CADisplayLink(target: self, selector: Selector("loop:"))
            displayLink?.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
        }
func loop(link:CADisplayLink) {
        if startTime == nil {
            startTime = link.timestamp
        }
        
        if link.timestamp - lastTime > 0.01 {            
            lastTime = link.timestamp
            // ここでSKLabelNode変更            
            refreshTimeLabel(Double(lastTime - startTime!))            
            self.view!.setNeedsDisplay()
        }
    }

迷路作成

ここを参考にしたのですが、迷路の作り方は色々あるようです。

迷路自動生成アルゴリズム
http://www5d.biglobe.ne.jp/stssk/maze/make.html

今回は立体ということもあり「穴掘り法(道延ばし法)」というのを利用しました。

  1. まず迷路を全て壁で埋め尽くす。
  2. 適当な基点を設定する。
  3. その基点からランダムに2マス穴を掘れる方向を探す。
  4. 2マス掘って、新たな基点とし、3を繰り返す。
  5. 穴に当たって掘れなくなったら、今までの基点から適当なものを選び新たな基点とする。

3Dモデル

今回は使ってませんが。

SceanKitですが、3Dモデルとして、COLLADAフォーマット(.dae)を扱うことができます。
ただ、これについてはよく指摘されているようですが、プロジェクトに追加すると、独自の形式に変換されているようです。
UIWebView + three.js でこのリソースを扱おうとしても、正しく読み込めません。
.datとか拡張子を変えて追加すると、正しく読み込めるようです。
(でも、おそらくSceneKitからは使えないような)

Unity

世の中的には Unityのほうがメジャーなのですが、SceneKitは無料なので、カジュアルに何か作るにはいいかな、と思います。

Unity無印のiOS出力アドオンっていつの間にか無料になってた。。。

16
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?