【 #TechBuzz 】
     第 12 回 Unity 開発技術勉強会




>>   0   >>   1   >>   2   >>   3   >>   4   >>
週末プログラミン
                                グ
                                で作る
                                カジュアルゲーム




         10
                                レーシング編



                                 のひな



>>   0   >>   1   >>   2   >>     3   >>   4   >>
>>   0   >>   1   >>   2   >>   3   >>   4   >>
PICTURE
              START
>>   0   >>   1   >>   2   >>   3   >>   4   >>
>>   0   >>   1   >>   2   >>   3   >>   4   >>
8
>>   0   >>   1   >>   2   >>   3   >>   4   >>
7
>>   0   >>   1   >>   2   >>   3   >>   4   >>
6
>>   0   >>   1   >>   2   >>   3   >>   4   >>
5
>>   0   >>   1   >>   2   >>   3   >>   4   >>
4
>>   0   >>   1   >>   2   >>   3   >>   4   >>
3
>>   0   >>   1   >>   2   >>   3   >>   4   >>
2
>>   0   >>   1   >>   2   >>   3   >>   4   >>
>>   0   >>   1   >>   2   >>   3   >>   4   >>
(= ・ ω ・)ノ<はじめ
            るよ~



>>   0   >>   1   >>   2   >>   3   >>   4   >>
じこしょうかい ( `・ ω ・ ´)
     名前:のひな

     六本木の会社で
     エンジニアやってます。

     お仕事でも趣味でも
     Unity な日々。

>>    0   >>   1   >>   2   >>   3   >>   4   >>
今日話すこと
     • 開発事例
      – レーシングゲームのはなし




               今回はどっちかというと初学者~中級者向け
               細かな開発 Tips まとめ

>>    0   >>    1   >>   2   >>   3   >>   4   >>
じゃあ早速、




>>   0   >>   1   >>   2   >>   3   >>   4   >>
>>   0   >>   1   >>   2   >>   3   >>   4   >>
レーシングゲームのはなし




>>   0    >>   1   >>   2   >>   3   >>   4   >>
Accel Beat
     • 障害物を避けなが
       ら車を運転し、走行
       距離を競うゲーム

     • 所謂ランニング系
       のジャンル



>>    0   >>   1    >>   2   >>   3   >>   4   >>
Accel Beat
     • ダウンロード数
      – 2万 DL くらい


     • ランキング
      – 最高 19 位くらい
          • iPad のレーシング
            カテゴリで




>>    0    >>   1    >>   2   >>   3   >>   4   >>
こんせぷと
     • デザイナ・エンジニアの二人で開発
     • 1回のゲーミングが 60 ~ 90 秒くらいで
       終わって、繰り返し遊んでもらう設計
     • 片手で遊べるカジュアル感
     • 演出にちょっとだけこだわる

     • でも、飽きちゃわないように1~2ヶ月
       くらいで作り切る感じで(・3・)

>>    0   >>   1   >>   2   >>   3   >>   4   >>
Main のループの流れ
     • 基本的にはひとつのコースをループする
     • スタート地点からコースの端までたどり
       着いたら、最初の地点に戻ってループす
       る




>>    0   >>   1   >>   2   >>   3   >>   4   >>
ステージ




>>   0   >>   1   >>   2   >>   3   >>   4   >>
ステージ
     • 基本的にはひとつの
       コースをループする
      – コースは全長 500m の
        ものを制作
      – これをつなげていくこ
        とでステージにする
          • 今回は1レベル 3000m
            にしたので 3000m と前
            後 3500m くらい


>>    0    >>   1   >>   2   >>   3   >>   4   >>
ステージ
     • 背景は SkyBox は利用しない
       – DrawCall がかかるのと思い通り
         の見た目にならなかったため
     • 背景専用のオブジェクトを用
       意する
       – 1つのステージをループするとい
         う性質のため、自機の数百 m 先
         に常に設置されるようにする

           • メモ:カメラワーク的に後ろを向
             くことはないため、前方のみカバ
             ーすれば良い




>>     0    >>   1   >>   2    >>   3   >>   4   >>
ステージ
     • アニメ調な演出
      – トゥーンシェーダ
        を基本的に用いる
          • Ippokratis
            Bournellis の Toon
            Shader($25.0) を
            利用




>>    0     >>     1     >>     2   >>   3   >>   4   >>
ステージ
     • アウトラインの当て方
     • 建物など板ポリゴンで表現するものは
       CutOut 系のシェーダを利用
      – 今回は Transparent/CutOut/Soft Edge Unlit を
        利用
      – Base Alpha cutoff のパラメータを調整してや
        ることで、アウトラインを表現する
     • ガードレールなど、一部のオブジェクト
       は直接テクスチャにアウトラインを書き
       込む
>>    0   >>    1   >>    2    >>   3    >>   4    >>
キャラクター




>>   0   >>   1   >>   2   >>   3   >>   4   >>
キャラクター
     • 基本的に画面上には一瞬でし
       か現れないので、認識できる
       程度にローポリで制作
      – けっこう雑に制作
     • ステージ同様トゥーンシェー
       ダを利用する




>>    0   >>   1   >>   2   >>   3   >>   4   >>
キャラクター
     • 男性は少し工夫
      – 髪型
          • 板ポリゴンを何枚も重ねて
            アフロを表現
          • トゥーンシェーダを利用す
            ると板ポリゴンのまわりに
            アウトラインを描いてしま
            うため、髪の毛だけはマテ
            リアルを分ける



>>    0    >>   1   >>   2   >>   3   >>   4   >>
レベル




>>   0   >>   1   >>   2   >>   3   >>   4   >>
レベル
     • 1レベル 3000m として
       、車や歩行者、ドラム
       缶などのオブジェクト
       を配置する
     • これをコース中にロー
       ドすることで、レベル
       とする
      – 今回は計 30 ( 90Km 分
        )のレベルをランダムに
        ロードしている

>>    0   >>   1   >>      2   >>   3   >>   4   >>
レベル
     • ゲームの起動時と、自機をループした直
       後のタイミングでロードする
      – ロードする場所はコースの終了地点より奥の
        方
          • コース内にロードすると、ループのタイミングで
            急に出現したようになり、不自然な挙動となるた
            め
     • 事前にあったオブジェクトはループの際
       に、自機と一緒にコース内に移動する
      – このとき、自機より後ろ側に行ったオブジェ
        クトはもう利用する必要がないため Destroy
>>    0    >>   1   >>   2   >>   3   >>   4   >>
ループの判定
     • 最初はコースの終了地点に透明な
       BoxCollider を置いていた
      – 自機の移動速度によっては飛び越えて衝突し
        ないことがあったため断念
     • コースの全長分以上の距離を走行したら
       、戻るように変更

      メモ:方法としては Collider に対して Raycast
       でも可
>>    0   >>   1   >>   2   >>   3   >>   4   >>
ポーズのしかた
     • 全オブジェクトに対して、以下の処理を
       かける = rigidbody.velocity;
        TempV
          TempAV = rigidbody.angularVelocity;

          rigidbody.velocity = Vector3.zero;
          rigidbody.angularVelocity = Vector3.zero;



     • アンポーズした際に、テンポラリに保存
       した定数を rigidbody に戻してやる
      – ついでに isKinematic をオンにしておいた方
        が安全かも
>>    0      >>       1      >>       2      >>       3   >>   4   >>
GUI
     • ほぼフォントで表現
      – OverDrive というフリーのフォントを利用
     • 一部画像
      – エナジーバーとか
          • 下地 / バー / フレームの3階層
            – ちなみにバーは 1 ピクセルの画像を条件に応じて拡縮して表現


     • 他の UI との競合がありうるため
      – isTapGUI とかして判定用のメソッドも作っておく



>>    0     >>   1   >>    2     >>   3   >>   4   >>
車




>>   0   >>   1   >>   2   >>   3   >>   4   >>
車
     • こちらも同様にトゥーンシェーダを用い
       る
     • 一部のアウトラインはテクスチャに直接
       描き込み




>>    0   >>   1   >>   2   >>   3   >>   4   >>
車
     • マフラーからの噴出物
      –煙
      – アフターバーナー
          • パーティクルを置いてパラメータを調整するだけ




>>    0    >>   1   >>   2   >>   3   >>   4   >>
自機の挙動
     • 基本的にはつねに前方移動、インプット
       があったときのみ左右のいずれかを向く
      – 単純に移動方向に対して以下を適応
      transform.position += (transform.forward * speed * Time.deltaTime);


      – 移動方向の算出も単純に以下のような感じ
      transform.Rotate(Vector3.up * curveSpeed * Time.deltaTime);




>>    0     >>       1      >>       2      >>       3      >>       4      >>
自機の挙動
     • 基本的には BoxCollider
     • 念のため Raycast も

     • Rigidbody の設定
       – Constrains を Position.x 以外すべて Freeze する
           • ゲームの性質上、衝突時に跳ねたり、後退したり、向きが変
             わったりということをしたくない
           • ただし、 Position.x だけはフラグを外す(左右の跳ね返りは
             許容する)
             – これをやらないと壁への衝突時などに、物体に刺さって動かな
               くなるという現象が起きる



>>     0    >>    1    >>    2   >>     3   >>     4   >>
自機の挙動
     • オブジェクトとの衝突時
      – 衝突したオブジェクトを前方に跳ね飛ばす
          • これも単純に以下のような処理を加えているだけ
          Velocity movement = transform.forward;
          movement.y = Mathf.Sqrt(
                           movement.x * movement.x
                         + movement.z * movement.z)
                       * Mathf.Tan(Mathf.Deg2Rad * direction);
          movement = movement.normalized;

          targetObj.getComponent<rigidbody>().velocity =
                        movement * driveSpeed * shotPower;


>>    0     >>       1     >>       2      >>      3      >>     4   >>
ポリスの挙動
     • 基本的なロジックは自機と一緒
     • 走行速度と移動方向だけ工夫して、単純な AI で
       自機を追いかけるようにする
      – 走行速度
          • 自機の速度に対して -1.5Km/h~+3.5Km/h くらいの速度で追
            いかける
            – じわじわと追いついて来るような感じ
      – 移動方向
          • 自機とポリスの x 軸の差が 5m 以上あれば、自機の方に向か
            って旋回する
            – 基本的には自機に衝突するように移動


>>    0     >>   1    >>   2   >>    3   >>    4   >>
衝突時の爆発
     • Unity Technologies の Detonator
       Explosion Framework を利用




>>     0   >>   1    >>   2   >>   3    >>   4   >>
おまけ
     • アイテムは演出上目立
       つようにアウトライン
       を少しだけ派手にする
      – アウトラインはオブジ
        ェクトのまわりに、同
        じオブジェクトを拡大
        して法線をひっくり返
        したものを配置して表
        現する

>>    0   >>   1   >>   2   >>   3   >>   4   >>
おまけ
     • キャラクターに衝突すると漫画のコマの
       ようなポップアップで演出




>>    0   >>   1   >>   2   >>   3   >>   4   >>
おまけ
     • サウンド
      – SE は Resources.Load() で呼ぶとと重たいので、事
        前に GameObject に貼り付ける
      – シーンをまたぐ直前に鳴る効果音は
        DontDestroyOnLoad() して、鳴り終わったら
        Destroy() する


     • バイブレーション
      – iPhoneUtils.Vibrate() が非推奨になったの
        で、 Handheld.Vibrate() を使いましょう

>>    0   >>    1   >>    2    >>   3     >>   4   >>
とまぁ、




>>   0   >>   1   >>   2   >>   3   >>   4   >>
雑に詰め込みましたが




>>   0   >>   1   >>   2   >>   3   >>   4   >>
こんな感じ。




>>   0   >>   1   >>   2   >>   3   >>   4   >>
参考になってたらいいけど。。
            。




>>   0   >>   1   >>   2   >>   3   >>   4   >>
以上です!ありがとうございま
           した。




>>   0   >>   1   >>   2   >>   3   >>   4   >>

週末プログラミングで作るカジュアルゲーム~レーシング編~

  • 1.
    【 #TechBuzz 】 第 12 回 Unity 開発技術勉強会 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 2.
    週末プログラミン グ で作る カジュアルゲーム 10 レーシング編 のひな >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 3.
    >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 4.
    PICTURE START >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 5.
    >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 6.
    8 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 7.
    7 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 8.
    6 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 9.
    5 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 10.
    4 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 11.
    3 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 12.
    2 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 13.
    >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 14.
    (= ・ ω・)ノ<はじめ るよ~ >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 15.
    じこしょうかい ( `・ω ・ ´) 名前:のひな 六本木の会社で エンジニアやってます。 お仕事でも趣味でも Unity な日々。 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 16.
    今日話すこと • 開発事例 – レーシングゲームのはなし 今回はどっちかというと初学者~中級者向け 細かな開発 Tips まとめ >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 17.
    じゃあ早速、 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 18.
    >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 19.
  • 20.
    Accel Beat • 障害物を避けなが ら車を運転し、走行 距離を競うゲーム • 所謂ランニング系 のジャンル >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 21.
    Accel Beat • ダウンロード数 – 2万 DL くらい • ランキング – 最高 19 位くらい • iPad のレーシング カテゴリで >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 22.
    こんせぷと • デザイナ・エンジニアの二人で開発 • 1回のゲーミングが 60 ~ 90 秒くらいで 終わって、繰り返し遊んでもらう設計 • 片手で遊べるカジュアル感 • 演出にちょっとだけこだわる • でも、飽きちゃわないように1~2ヶ月 くらいで作り切る感じで(・3・) >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 23.
    Main のループの流れ • 基本的にはひとつのコースをループする • スタート地点からコースの端までたどり 着いたら、最初の地点に戻ってループす る >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 24.
    ステージ >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 25.
    ステージ • 基本的にはひとつの コースをループする – コースは全長 500m の ものを制作 – これをつなげていくこ とでステージにする • 今回は1レベル 3000m にしたので 3000m と前 後 3500m くらい >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 26.
    ステージ • 背景は SkyBox は利用しない – DrawCall がかかるのと思い通り の見た目にならなかったため • 背景専用のオブジェクトを用 意する – 1つのステージをループするとい う性質のため、自機の数百 m 先 に常に設置されるようにする • メモ:カメラワーク的に後ろを向 くことはないため、前方のみカバ ーすれば良い >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 27.
    ステージ • アニメ調な演出 – トゥーンシェーダ を基本的に用いる • Ippokratis Bournellis の Toon Shader($25.0) を 利用 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 28.
    ステージ • アウトラインの当て方 • 建物など板ポリゴンで表現するものは CutOut 系のシェーダを利用 – 今回は Transparent/CutOut/Soft Edge Unlit を 利用 – Base Alpha cutoff のパラメータを調整してや ることで、アウトラインを表現する • ガードレールなど、一部のオブジェクト は直接テクスチャにアウトラインを書き 込む >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 29.
    キャラクター >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 30.
    キャラクター • 基本的に画面上には一瞬でし か現れないので、認識できる 程度にローポリで制作 – けっこう雑に制作 • ステージ同様トゥーンシェー ダを利用する >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 31.
    キャラクター • 男性は少し工夫 – 髪型 • 板ポリゴンを何枚も重ねて アフロを表現 • トゥーンシェーダを利用す ると板ポリゴンのまわりに アウトラインを描いてしま うため、髪の毛だけはマテ リアルを分ける >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 32.
    レベル >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 33.
    レベル • 1レベル 3000m として 、車や歩行者、ドラム 缶などのオブジェクト を配置する • これをコース中にロー ドすることで、レベル とする – 今回は計 30 ( 90Km 分 )のレベルをランダムに ロードしている >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 34.
    レベル • ゲームの起動時と、自機をループした直 後のタイミングでロードする – ロードする場所はコースの終了地点より奥の 方 • コース内にロードすると、ループのタイミングで 急に出現したようになり、不自然な挙動となるた め • 事前にあったオブジェクトはループの際 に、自機と一緒にコース内に移動する – このとき、自機より後ろ側に行ったオブジェ クトはもう利用する必要がないため Destroy >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 35.
    ループの判定 • 最初はコースの終了地点に透明な BoxCollider を置いていた – 自機の移動速度によっては飛び越えて衝突し ないことがあったため断念 • コースの全長分以上の距離を走行したら 、戻るように変更 メモ:方法としては Collider に対して Raycast でも可 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 36.
    ポーズのしかた • 全オブジェクトに対して、以下の処理を かける = rigidbody.velocity; TempV TempAV = rigidbody.angularVelocity; rigidbody.velocity = Vector3.zero; rigidbody.angularVelocity = Vector3.zero; • アンポーズした際に、テンポラリに保存 した定数を rigidbody に戻してやる – ついでに isKinematic をオンにしておいた方 が安全かも >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 37.
    GUI • ほぼフォントで表現 – OverDrive というフリーのフォントを利用 • 一部画像 – エナジーバーとか • 下地 / バー / フレームの3階層 – ちなみにバーは 1 ピクセルの画像を条件に応じて拡縮して表現 • 他の UI との競合がありうるため – isTapGUI とかして判定用のメソッドも作っておく >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 38.
    車 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 39.
    • こちらも同様にトゥーンシェーダを用い る • 一部のアウトラインはテクスチャに直接 描き込み >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 40.
    • マフラーからの噴出物 –煙 – アフターバーナー • パーティクルを置いてパラメータを調整するだけ >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 41.
    自機の挙動 • 基本的にはつねに前方移動、インプット があったときのみ左右のいずれかを向く – 単純に移動方向に対して以下を適応 transform.position += (transform.forward * speed * Time.deltaTime); – 移動方向の算出も単純に以下のような感じ transform.Rotate(Vector3.up * curveSpeed * Time.deltaTime); >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 42.
    自機の挙動 • 基本的には BoxCollider • 念のため Raycast も • Rigidbody の設定 – Constrains を Position.x 以外すべて Freeze する • ゲームの性質上、衝突時に跳ねたり、後退したり、向きが変 わったりということをしたくない • ただし、 Position.x だけはフラグを外す(左右の跳ね返りは 許容する) – これをやらないと壁への衝突時などに、物体に刺さって動かな くなるという現象が起きる >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 43.
    自機の挙動 • オブジェクトとの衝突時 – 衝突したオブジェクトを前方に跳ね飛ばす • これも単純に以下のような処理を加えているだけ Velocity movement = transform.forward; movement.y = Mathf.Sqrt( movement.x * movement.x + movement.z * movement.z) * Mathf.Tan(Mathf.Deg2Rad * direction); movement = movement.normalized; targetObj.getComponent<rigidbody>().velocity = movement * driveSpeed * shotPower; >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 44.
    ポリスの挙動 • 基本的なロジックは自機と一緒 • 走行速度と移動方向だけ工夫して、単純な AI で 自機を追いかけるようにする – 走行速度 • 自機の速度に対して -1.5Km/h~+3.5Km/h くらいの速度で追 いかける – じわじわと追いついて来るような感じ – 移動方向 • 自機とポリスの x 軸の差が 5m 以上あれば、自機の方に向か って旋回する – 基本的には自機に衝突するように移動 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 45.
    衝突時の爆発 • Unity Technologies の Detonator Explosion Framework を利用 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 46.
    おまけ • アイテムは演出上目立 つようにアウトライン を少しだけ派手にする – アウトラインはオブジ ェクトのまわりに、同 じオブジェクトを拡大 して法線をひっくり返 したものを配置して表 現する >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 47.
    おまけ • キャラクターに衝突すると漫画のコマの ようなポップアップで演出 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 48.
    おまけ • サウンド – SE は Resources.Load() で呼ぶとと重たいので、事 前に GameObject に貼り付ける – シーンをまたぐ直前に鳴る効果音は DontDestroyOnLoad() して、鳴り終わったら Destroy() する • バイブレーション – iPhoneUtils.Vibrate() が非推奨になったの で、 Handheld.Vibrate() を使いましょう >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 49.
    とまぁ、 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 50.
    雑に詰め込みましたが >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 51.
    こんな感じ。 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 52.
    参考になってたらいいけど。。 。 >> 0 >> 1 >> 2 >> 3 >> 4 >>
  • 53.
    以上です!ありがとうございま した。 >> 0 >> 1 >> 2 >> 3 >> 4 >>