1 00:00:01,290 --> 00:00:03,940 Unity 4.3 より新たな2D機能が追加されました。 2 00:00:03,940 --> 00:00:05,939 我々の作成したデモを元に、 3 00:00:05,939 --> 00:00:08,290 これらの機能を解説したいと思います。 4 00:00:08,290 --> 00:00:11,520 この「Tower Bridge Defence」というゲームは 5 00:00:11,520 --> 00:00:13,770 宇宙人の侵略に晒されている 6 00:00:13,770 --> 00:00:15,550 ロンドンのタワーブリッジを描いたデモです。 7 00:00:15,550 --> 00:00:18,950 これは、スプライトのみで構成された物理駆動のゲームで、 8 00:00:18,950 --> 00:00:22,210 Unityにおける2Dゲーム制作の理解に役立つのではないかと思います。 9 00:00:23,470 --> 00:00:25,470 この動画では 10 00:00:25,470 --> 00:00:28,180 デモの背景と前景の作り方 11 00:00:28,180 --> 00:00:30,180 キャラクター、エフェクト、カメラの追従 12 00:00:30,180 --> 00:00:31,630 アニメーションとスクリプトについて解説します。 13 00:00:31,630 --> 00:00:35,630 まずは、Unity 2Dの基本的な操作を説明しましょう。 14 00:00:36,860 --> 00:00:40,290 まず、2D機能を使うにあたって 15 00:00:40,290 --> 00:00:42,220 「Editor Behaviour Mode」を2Dにしてください。 16 00:00:43,040 --> 00:00:45,040 新規プロジェクトウィザードのドロップダウン 17 00:00:45,040 --> 00:00:48,040 またはメニューから Edit > Project Settings > Editor 18 00:00:48,040 --> 00:00:50,540 で設定出来ます。 19 00:00:53,170 --> 00:00:55,170 この設定により 20 00:00:55,170 --> 00:00:57,170 インポートされたテクスチャーはデフォルトでスプライトに設定され、 21 00:00:57,170 --> 00:00:59,630 「Scene View」のデフォルトの表示は2Dになります。 22 00:00:59,630 --> 00:01:01,630 このモードでは2Dゲーム制作を行いやすい様に 23 00:01:01,630 --> 00:01:04,420 ビューは並行投影になります。 24 00:01:04,420 --> 00:01:06,800 そして、ビューの右上に表示されている3D Gizmoが非表示になり、 25 00:01:06,800 --> 00:01:09,190 より広いスペースを使えるようになります。 26 00:01:09,190 --> 00:01:11,940 この設定以外の点では 27 00:01:11,940 --> 00:01:16,240 2Dのワークフローは従来の3Dゲームを作るアプローチとよく似ています。 28 00:01:17,040 --> 00:01:20,040 なので、既にUnityを使ったことがある方なら 29 00:01:20,040 --> 00:01:22,040 すぐに2Dゲームを作ることができると言うことです。 30 00:01:22,920 --> 00:01:24,920 また、2Dと3Dの要素は混在できるので 31 00:01:24,920 --> 00:01:27,210 2Dゲームに3Dの要素を加える事も 32 00:01:27,210 --> 00:01:31,720 またその逆に3Dのゲームに2Dの要素を加えることもできます。 33 00:01:33,360 --> 00:01:35,490 ではデモプロジェクトを元に 34 00:01:35,490 --> 00:01:39,310 我々がどのようにステージを作成したのかを見てみましょう。 35 00:01:40,810 --> 00:01:42,810 まず、Photoshopでステージ構成の概要を作成し 36 00:01:42,810 --> 00:01:44,810 そこからレイアウトを決めました。 37 00:01:45,310 --> 00:01:47,310 レイヤー毎に書き出す事で、 38 00:01:47,310 --> 00:01:50,310 Unityのスプライトタイプとしてインポートできます 39 00:01:58,370 --> 00:02:01,300 背景を視点に応じて移動させるため 40 00:02:01,300 --> 00:02:03,660 いくつかの背景要素は別にして 41 00:02:03,660 --> 00:02:06,510 Background Sorting レイヤーに配置します。 42 00:02:06,510 --> 00:02:09,650 これはUnityの新たなもう一つの2D開発機能です。 43 00:02:10,150 --> 00:02:12,840 このレイヤーにすべての背景を追加する事で、 44 00:02:12,840 --> 00:02:15,150 Order In LayerというSprite Rendererのプロパティで 45 00:02:15,150 --> 00:02:17,370 一括して描画順番を変更する事ができます。 46 00:02:17,370 --> 00:02:19,370 配置位置が決まったなら 47 00:02:19,370 --> 00:02:21,370 Sorting Layerの”Background”をロックする事で 48 00:02:21,370 --> 00:02:23,370 前景の要素を追加するときに 49 00:02:23,370 --> 00:02:27,370 間違えて背景を動かせることを予防できます。 50 00:02:27,750 --> 00:02:29,750 右上のLayersドロップダウンで 51 00:02:29,750 --> 00:02:31,750 この設定を指定できます。 52 00:02:32,810 --> 00:02:35,530 背景は飾りの要素だけですので、 53 00:02:35,530 --> 00:02:37,530 スプライト以外のコンポーネントは必要ありません。 54 00:02:37,530 --> 00:02:39,530 背景オブジェクトの親オブジェクトには 55 00:02:39,530 --> 00:02:41,530 視点に応じて位置を操作する 56 00:02:41,530 --> 00:02:46,200 BackgroundParallaxという単純なスクリプトが追加してあります。 57 00:02:46,200 --> 00:02:48,640 このスクリプトに関しての詳しい説明は 58 00:02:48,640 --> 00:02:50,640 Scriptsフォルダにあるスクリプトのコメントを参照して下さい。 59 00:02:54,910 --> 00:02:58,910 次は、前景の要素、キャラクターの作成です。 60 00:02:59,790 --> 00:03:02,280 デザインはロンドンのタワーブリッジの中に 61 00:03:02,280 --> 00:03:03,460 UFOが着陸した状況です。 62 00:03:03,460 --> 00:03:05,460 プレイヤーはフィールド内を動き回り、 63 00:03:05,460 --> 00:03:07,460 敵は空から登場して 64 00:03:07,460 --> 00:03:09,210 フィールドの中を移動します。 65 00:03:09,210 --> 00:03:11,210 そういった、キャラクターの移動のために、 66 00:03:11,210 --> 00:03:13,630 各前景の部分にはコライダーが必要です。 67 00:03:13,630 --> 00:03:17,630 大体のフィールドには2DのBox Colliderで良いのですが、 68 00:03:17,630 --> 00:03:20,630 UFOの形はかなり複雑です。 69 00:03:22,500 --> 00:03:24,500 UnityのPolygon Colliderはスプライトの形に基づき 70 00:03:24,500 --> 00:03:28,700 自動的にコライダーを作成してくれます。 71 00:03:28,720 --> 00:03:32,050 また、生成されたコライダーの形を手動で調整する事も可能です。 72 00:03:32,050 --> 00:03:34,160 ポイントの移動、追加、削除で 73 00:03:34,160 --> 00:03:38,160 コライダーの形を歩かせるのに適切な形にします。 74 00:03:38,660 --> 00:03:40,660 前景を背景より手前に表示するために 75 00:03:40,660 --> 00:03:43,150 Tags and Layersマネジャーに 76 00:03:43,150 --> 00:03:45,590 "Foregrounds"ソートレイヤーを作成してあります。 77 00:03:48,870 --> 00:03:50,870 次は、プレイヤーキャラクターを見てみましょう。 78 00:03:53,700 --> 00:03:55,590 プレイヤーキャラクターもPhotoshopでデザインしました。 79 00:03:55,590 --> 00:03:58,590 2Dゲームに合うように 80 00:03:58,590 --> 00:04:02,590 Raymanの様に手足が独立したデザインです。 81 00:04:03,590 --> 00:04:07,590 もしくは、スプライトアニメを用いた コマアニメーションで表現する事も可能です。 82 00:04:08,140 --> 00:04:12,640 そのアプローチは後で背景の鳥に使用します。 83 00:04:15,070 --> 00:04:17,070 キャラクターの手足を別々に動かしたいので 84 00:04:17,070 --> 00:04:20,190 Unityが別のスプライトとしてインポートされる様に 85 00:04:20,190 --> 00:04:26,190 それぞれ分割して配置します。 86 00:04:27,000 --> 00:04:32,760 これにより、全てのスプライトを独立的に動く様に配置する事ができます。 87 00:04:33,090 --> 00:04:35,490 新しい"Character"ソートレイヤーに配置して 88 00:04:35,490 --> 00:04:40,160 PositionのZの値を入力して描画順を設定します。 89 00:04:48,810 --> 00:04:50,810 プレイヤーキャラクターのスプライトは空のGameObjectの子供に設定し 90 00:04:50,810 --> 00:04:52,810 親のオブジェクトにはコントロールスクリプト、コライダー、 91 00:04:52,810 --> 00:04:56,590 フィジックス、その他を付加します。 92 00:04:56,590 --> 00:04:58,590 その後、新しくなったAnimation Windowで 93 00:04:58,590 --> 00:05:03,040 待機、移動、ジャンプ、攻撃、死亡の時の 94 00:05:03,040 --> 00:05:06,900 各スプライトのパーツの動きを設定します。 95 00:05:07,090 --> 00:05:09,790 Animation windowのDopesheetビューを使う事で 96 00:05:09,790 --> 00:05:11,790 簡単に設定ができます。 97 00:05:13,410 --> 00:05:16,000 親オブジェクトにアニメーションを追加して 98 00:05:16,000 --> 00:05:19,400 子オブジェクトのKeyframeを作成します。 99 00:05:19,400 --> 00:05:21,400 再生位置を動かし、キャラクターのパーツを動かして 100 00:05:21,400 --> 00:05:25,400 自動的にKeyframeを作ってアニメーションを作る事ができます。 101 00:05:27,310 --> 00:05:29,640 CurveとDopesheet、2つの表示を切り替える事で 102 00:05:29,640 --> 00:05:36,730 タイミング及びデザインを調整も 103 00:05:36,730 --> 00:05:38,730 完成したアニメーションを 104 00:05:38,730 --> 00:05:43,370 ステートマシーンを使って切り替える事が出来ます。 105 00:05:45,270 --> 00:05:47,270 キャラクターのAnimator Controllerは bipedを使用していないので 106 00:05:47,270 --> 00:05:50,570 Apply Root Motionのチェックを解除して 107 00:05:50,570 --> 00:05:53,670 Animate Physicsを有効にします。 108 00:05:53,670 --> 00:05:57,670 これで、物理エンジンで正しくアニメーションされる様になります。 109 00:05:57,760 --> 00:05:59,850 フィールド上を移動する為に 110 00:05:59,850 --> 00:06:02,230 プレイヤーの足元にはCircle Colliderがあります。 111 00:06:02,230 --> 00:06:04,560 また、体を囲うBox Colliderもあります。 112 00:06:04,560 --> 00:06:07,060 これにより、段差をスムーズに乗り越える事ができ 113 00:06:07,060 --> 00:06:09,450 ジャンプの時は頭が天井にをぶつかるようになります。 114 00:06:09,800 --> 00:06:12,530 キャラクターのアニメーションを制御するために、 115 00:06:12,530 --> 00:06:16,030 2Dフィジックスで動かすスクリプトを作りました。 116 00:06:16,030 --> 00:06:18,030 フィジクスを使ってキャラクターと 117 00:06:18,030 --> 00:06:20,030 敵を動かしてもっとダイナミックな 118 00:06:20,030 --> 00:06:21,420 ゲームプレーが可能になります。 119 00:06:21,420 --> 00:06:23,810 キャラクターのPlayerControlスクリプトでは 120 00:06:23,810 --> 00:06:25,810 プレイヤーの入力をチェックします。 121 00:06:25,810 --> 00:06:27,810 入力は物理制御を通してキャラクターを移動させ、 122 00:06:27,810 --> 00:06:30,760 また、この入力をAnimatorに渡し 123 00:06:30,760 --> 00:06:33,480 ステートから正しいアニメーションを選択して 124 00:06:33,480 --> 00:06:37,470 それぞれのアニメーション間をスムーズに遷移させます。 125 00:06:40,470 --> 00:06:43,470 アニメーションからステートを作成すると便利な点は 126 00:06:43,470 --> 00:06:47,470 物理の速度に応じてアニメーションの速度を変化させられる事です。 127 00:06:47,470 --> 00:06:51,860 速度に応じてアニメーションを切り替える必要はありません。 128 00:07:23,120 --> 00:07:25,120 FixedUpdateという関数は物理更新の毎に呼び出されます。 129 00:07:25,120 --> 00:07:28,580 この関数で水平方向の入力を取得し、 130 00:07:28,580 --> 00:07:32,580 AnimatorのSpeedパラメータに入れます。 131 00:07:35,950 --> 00:07:37,950 ステートマシーンの待機と移動間の遷移条件は 132 00:07:37,950 --> 00:07:41,710 Speedパラメータが0.1以上かどうか、になります。 133 00:07:41,710 --> 00:07:44,020 その状況になると、アニメーターは待機のステートから 134 00:07:44,020 --> 00:07:46,020 移動のステートにブレンドします。 135 00:07:51,850 --> 00:07:54,850 次は、プレイヤーのRigidbody2Dという2D物理要素に 136 00:07:54,850 --> 00:07:58,180 力を加えてプレイヤーを動かします。 137 00:07:59,620 --> 00:08:02,520 キャラクターの向いている向きを制御するのにも 138 00:08:02,520 --> 00:08:06,700 水平方向の入力を利用します。 139 00:08:07,710 --> 00:08:10,550 Unityでは、左キーを押すと-1が返り 140 00:08:10,550 --> 00:08:14,570 右キーを押すと+1が返ってきます。 141 00:08:15,070 --> 00:08:18,700 入力された値に応じて、Flip()関数で 142 00:08:18,700 --> 00:08:21,470 キャラクターのXスケールを反転させて 143 00:08:21,470 --> 00:08:24,560 反対側を向いている状態を表現します。 144 00:08:26,840 --> 00:08:28,840 地面を接地しているかどうかを決めるために、 145 00:08:28,840 --> 00:08:31,600 Groundというレーヤーを追加して 146 00:08:31,600 --> 00:08:34,980 すべての歩ける地面に適用します。 147 00:08:43,390 --> 00:08:45,960 そして2DのLinecastという関数を使い 148 00:08:45,960 --> 00:08:47,960 キャラクターの足元にGroundレイヤーがあるかどうかを 149 00:08:47,960 --> 00:08:50,230 チェックできます。 150 00:08:50,230 --> 00:08:52,770 より簡単に変更できるようにするため、 151 00:08:52,770 --> 00:08:54,770 接地判定用の空のGameObjectを追加しました 152 00:08:56,770 --> 00:08:59,080 この空GameObjectにGizmoを追加する事で 153 00:08:59,080 --> 00:09:01,080 接地判定の距離を調整できます。 154 00:09:03,080 --> 00:09:05,480 ゲーム中は 155 00:09:05,480 --> 00:09:07,950 キャラクターは地面に設置している状況でのみでジャンプできます。 156 00:09:08,450 --> 00:09:10,450 プレイヤーの制御の詳細は、 157 00:09:10,450 --> 00:09:12,640 スクリプトのコメントを確認してみてください。 158 00:09:12,640 --> 00:09:15,640 プレイヤーの攻撃に関しては後ほどお話したいと思います。 159 00:09:15,870 --> 00:09:17,870 次は、このデモで 160 00:09:17,870 --> 00:09:19,870 カメラがどのような動きをするか見てみましょう。 161 00:09:21,290 --> 00:09:24,350 2Dゲームにおいても、3Dゲームと変わらず 162 00:09:24,350 --> 00:09:27,350 カメラの動作はとても重要です。 163 00:09:27,820 --> 00:09:30,580 古典的2Dアクションのカメラを学ぶために 164 00:09:30,580 --> 00:09:35,620 スーパーファミコンのスーパーマリオワールドを見てみましょう。 165 00:09:36,650 --> 00:09:38,650 スーパーマリオワールドでは 166 00:09:38,650 --> 00:09:42,650 カメラは横方向に追従しますが 167 00:09:42,650 --> 00:09:47,650 画面の中心にはキャラクターに追従しない遊び幅があります。 168 00:09:49,340 --> 00:09:51,630 この遊び幅の外側に動こうとすると 169 00:09:51,630 --> 00:09:54,040 カメラはプレイヤーの位置に追従します。 170 00:09:54,040 --> 00:09:56,860 高さ方向に対しては一定段階の高さを保ちますが、 171 00:09:56,860 --> 00:09:59,540 我々のゲームに関してはその必要はありません。 172 00:09:59,540 --> 00:10:03,540 ステージの横幅はそれほど長くなく 173 00:10:03,540 --> 00:10:05,870 殆どが画面に収まる広さのステージです。 174 00:10:07,210 --> 00:10:11,210 ですので、カメラの水平の動きと垂直の動きは同じ動きにします。 175 00:10:18,770 --> 00:10:20,770 mainCameraのGameObjectに付属している 176 00:10:20,770 --> 00:10:23,130 CameraFollowというスクリプトを見てみましょう。 177 00:10:23,130 --> 00:10:25,130 どのような働きをするのか、コメントを確認してください。 178 00:10:26,130 --> 00:10:28,840 色々な機能の中で最も重要なことは 179 00:10:28,840 --> 00:10:30,840 ヒーローの宇宙人を倒す能力です。 180 00:10:32,730 --> 00:10:36,330 ヒーローのバズーカは発砲後の反動アニメーションがあります。 181 00:10:36,330 --> 00:10:38,890 このアクションはいくつかの部分に分かれています。 182 00:10:38,890 --> 00:10:41,640 Fireキーの入力があると 183 00:10:41,640 --> 00:10:43,960 ロケットを発射して、オーディオを再生して 184 00:10:43,960 --> 00:10:47,960 アニメーションステートを再生します。 185 00:10:47,960 --> 00:10:49,960 もっと詳しく調べてみましょう。 186 00:10:49,960 --> 00:10:52,410 Runや他のアニメーションの再生中に 187 00:10:52,410 --> 00:10:54,410 Shootアニメーションを再生するのため、 188 00:10:54,410 --> 00:10:57,410 Shootingという別のレイヤーを作成しました。 189 00:10:57,670 --> 00:10:59,670 Weightプロパティを1にすると 190 00:10:59,670 --> 00:11:02,530 Shootingレイヤーに含まれるパーツは 191 00:11:02,530 --> 00:11:06,530 ベースレイヤーの動きを完全に上書きします。 192 00:11:20,490 --> 00:11:22,490 このレイヤーは、プログラムからShootトリガーを呼び出されると 193 00:11:22,490 --> 00:11:25,350 いつでもShootアニメーションに切り替わります。 194 00:11:27,350 --> 00:11:30,540 Gunスクリプトのこの機能を調べてみましょう。 195 00:11:32,700 --> 00:11:35,140 ここで、アニメーターを操作して 196 00:11:35,140 --> 00:11:37,400 ShootトリガーをTrueにします。 197 00:11:37,400 --> 00:11:40,510 トリガーはスイッチのように 198 00:11:40,510 --> 00:11:43,240 次のフレームにFalseに戻り、再び使用できるようになります。 199 00:11:43,240 --> 00:11:45,510 これは攻撃のようなアクションにぴったりです。 200 00:11:46,010 --> 00:11:48,670 アニメーションをセットし、 201 00:11:48,670 --> 00:11:50,670 ロケットもこのスクリプトで発射します。 202 00:11:50,670 --> 00:11:52,670 オーディオを再生して 203 00:11:52,670 --> 00:11:54,670 プレイヤーの向いている方向に対して 204 00:11:54,670 --> 00:11:59,770 ロケットの速度を設定します。 205 00:12:01,270 --> 00:12:03,930 このスクリプトはヒーローの 206 00:12:03,930 --> 00:12:05,290 Gunという空のGameObjectに付属します。 207 00:12:05,290 --> 00:12:08,070 空のGameObjectにスクリプトを追加するのは、 208 00:12:08,070 --> 00:12:11,070 簡単にロケットの発射位置を設定できるようにするためです。 209 00:12:11,660 --> 00:12:15,660 バズーカの先に空のGameObjectを配置して 210 00:12:15,660 --> 00:12:21,010 オブジェクトの位置にロケットが生成されるようにします。 211 00:12:40,240 --> 00:12:42,800 ロケットは2DRigidbodyを持って 212 00:12:42,800 --> 00:12:46,800 それに速度を与えて動かします。 213 00:12:46,800 --> 00:12:51,090 スプライトの排気炎を付け 214 00:12:51,090 --> 00:12:53,090 パーティクルシステムの煙も足します。 215 00:12:54,880 --> 00:12:58,480 パーティクルシステムも新たなスプライト版機能が追加されました。 216 00:12:58,480 --> 00:13:02,480 煙のコマが描かれたスプライトをマテリアルに追加する事で 217 00:13:02,480 --> 00:13:07,140 簡単にスプライトアニメーションのパーティクルを作成できます。 218 00:13:16,120 --> 00:13:18,930 敵またはフィールドにロケットが当たると 219 00:13:18,930 --> 00:13:20,930 ロケットは消え 220 00:13:20,930 --> 00:13:22,930 爆発が生成されます。 221 00:13:22,930 --> 00:13:25,930 爆発は単純なコマアニメーションを行うスプライトです。 222 00:13:27,730 --> 00:13:32,310 Sorting Layerで前景の最後に描画されるようにします。 223 00:13:36,170 --> 00:13:38,170 このようなスプライトに基づいたアニメーションの追加は、 224 00:13:38,170 --> 00:13:40,170 Project Panelからファイルを選んで 225 00:13:40,170 --> 00:13:43,170 Sprite Modeを"Multiple"にします。 226 00:13:44,570 --> 00:13:46,570 これでスプライトエディタを使い 227 00:13:46,570 --> 00:13:49,750 手動、もしくは自動的に分割する事ができます。 228 00:13:49,750 --> 00:13:52,400 ファイルをスプライトに設定する利点は、 229 00:13:52,400 --> 00:13:54,400 この様にApplyをクリックするだけで 230 00:13:54,400 --> 00:13:56,760 Unityはファイルの子供としてそれぞれのスプライトを生成し 231 00:13:56,760 --> 00:13:58,760 そのスプライトをそのまま使う事が出来ます。 232 00:13:59,700 --> 00:14:01,690 これがロケットの構造です。 233 00:14:01,690 --> 00:14:03,690 どのようにして敵を倒すのかは、 234 00:14:03,690 --> 00:14:06,530 後ほど敵の項目でお話したいと思います。 235 00:14:07,100 --> 00:14:09,440 話をプレイヤーキャラクターに戻して 236 00:14:09,440 --> 00:14:12,190 HPとダメージのことを調べましょう。 237 00:14:12,190 --> 00:14:14,190 HPはfloatとして保存されています。 238 00:14:14,190 --> 00:14:18,190 敵からのダメージはTakeDamage関数を呼び出して与えます。 239 00:14:18,540 --> 00:14:20,540 プレイヤーが簡単に倒されてしまうのを避けるため、 240 00:14:20,540 --> 00:14:22,540 前回のダメージからrepeatDamagePeriodが経過した場合のみ 241 00:14:22,540 --> 00:14:25,340 ダメージを受けます。 242 00:14:26,520 --> 00:14:29,130 また、敵から逃げ易くするため、 243 00:14:29,130 --> 00:14:31,130 そしてプレイヤーのダメージを表現するため、 244 00:14:31,130 --> 00:14:34,130 ダメージを受けたキャラクターをヒットバックさせます。 245 00:14:34,840 --> 00:14:40,540 TakeDamage関数で一時的にプレイヤーのジャンプを止め、 246 00:14:40,540 --> 00:14:44,540 敵からキャラクターへの方向に物理的な力を与えて動かします。 247 00:14:46,120 --> 00:14:50,680 hurtForceの変数はInspectorで表示しているので、 248 00:14:50,680 --> 00:14:55,320 スクリプトを編集せずにゲーム要素の調整が出来ます。 249 00:14:55,320 --> 00:14:57,320 ダメージ表現に加えて 250 00:14:57,320 --> 00:14:59,810 もちろんプレイヤーのHPも減らした上で 251 00:14:59,810 --> 00:15:02,200 HPバーを更新します。 252 00:15:02,200 --> 00:15:06,620 HPの差を表示するのためにバーの長さを縮め 253 00:15:06,620 --> 00:15:08,880 色を緑から赤に補間します。 254 00:15:09,820 --> 00:15:14,640 最大HPに対する現在のHPの比率を計算すれば出来ますね。 255 00:15:14,640 --> 00:15:17,870 HPバーはシンプルなスプライト2つで構成されています。 256 00:15:17,870 --> 00:15:20,960 バーの外周部分とバーの部分です。 257 00:15:21,740 --> 00:15:23,740 これらもPhotoshopでデザインして 258 00:15:23,740 --> 00:15:25,950 2つのテクスチャを書き出しました。 259 00:15:25,950 --> 00:15:27,950 このスプライトのImport Settingsで 260 00:15:27,950 --> 00:15:30,470 Pivotを左の中央に設定して 261 00:15:30,470 --> 00:15:34,050 スケールを小さくした時に左側に縮んでいく様にします。 262 00:15:48,570 --> 00:15:50,570 この2つのスプライトは 263 00:15:50,570 --> 00:15:52,570 プレイヤーに追従するスクリプトを追加した 264 00:15:52,570 --> 00:15:54,570 空のGameObjectの子供として配置します。 265 00:15:54,570 --> 00:15:58,620 プレイヤーのGameObjectの位置とオフセットを足すので 266 00:15:58,620 --> 00:16:00,620 表示位置はInspectorで調整できます。 267 00:16:16,210 --> 00:16:18,210 プレイヤーは残りHPが0になると 268 00:16:18,210 --> 00:16:20,210 コライダーをトリガーモードに設定されるので 269 00:16:20,210 --> 00:16:22,620 プレイヤーはステージを突き破って落ちます。 270 00:16:22,620 --> 00:16:24,620 その時、最前面に描画される様に 271 00:16:24,620 --> 00:16:30,190 SpriteRendererを”UI”ソートレイヤーに移動させます。 272 00:16:31,590 --> 00:16:34,220 プレイヤーの死亡アニメーションは、2段階で構成されます。 273 00:16:34,220 --> 00:16:37,250 最初の”Death”は、帽子と武器を落とします。 274 00:16:37,250 --> 00:16:38,630 2番目は”Falling”という名前です。 275 00:16:38,630 --> 00:16:40,630 アニメータにExit Timeのコンディションを使って 276 00:16:40,630 --> 00:16:44,000 ”Death”アニメーションが終わると 277 00:16:44,000 --> 00:16:47,230 自動的に”Falling”に遷移します。 278 00:16:50,770 --> 00:16:52,770 最後に、プレイヤの動きと攻撃を停止させるために 279 00:16:52,770 --> 00:16:57,270 PlayerControlとGunのスクリプトを無効にします。 280 00:16:58,340 --> 00:17:00,730 Die関数はPublicなので 281 00:17:00,730 --> 00:17:03,330 どこからでも呼び出せます。 282 00:17:03,330 --> 00:17:05,040 例えば、水に落ちた時。 283 00:17:05,040 --> 00:17:07,730 プレイヤーが水に落ちるとゲームをリセットするために、 284 00:17:07,730 --> 00:17:09,730 トリガーコライダーとスクリプトだけがある 285 00:17:09,730 --> 00:17:12,460 KillTriggerという名前のGameObjectがあります。 286 00:17:12,460 --> 00:17:15,010 Removerスクリプトには 287 00:17:15,010 --> 00:17:17,010 川にザブンと飛び込んだ敵を消して 288 00:17:17,010 --> 00:17:20,780 飛沫のアニメーションとサウンドを再生する役割があります。 289 00:17:21,440 --> 00:17:24,000 しかしこのコライダーにプレイヤーが衝突すると 290 00:17:24,000 --> 00:17:27,089 PlayerHealthスクリプトの”Die”関数呼び出して 291 00:17:27,089 --> 00:17:30,090 プレイヤーを画面外に動かしている間カメラの追従を無効にし、 292 00:17:30,090 --> 00:17:35,090 2秒後にステージをリセットするコルーチンを実行します。 293 00:17:37,070 --> 00:17:39,070 さて、プレイヤーキャラクターの死について考えるのではなく、 294 00:17:39,070 --> 00:17:42,070 彼が生き残るために何をあげればいいかを考えましょう。 295 00:17:42,480 --> 00:17:47,480 このゲームでは2種類のプレイヤーを助けるアイテムボックスが落下してきます。 296 00:17:47,480 --> 00:17:49,910 一つは爆弾、もう一つは救急箱です。 297 00:17:50,410 --> 00:17:52,960 このアイテムは2つの部分で構成されています。 298 00:17:52,960 --> 00:17:55,690 箱本体と落下傘の部分です。 299 00:17:58,040 --> 00:18:03,310 これらの要素は空のオブジェクトでグループにして動かす事ができます。 300 00:18:03,760 --> 00:18:07,760 落下傘の中心を親オブジェクトの中心に位置します。 301 00:18:09,040 --> 00:18:14,900 これで箱を、落下中左右に揺れるようにできます。 302 00:18:15,300 --> 00:18:17,300 オブジェクトが落下させる為には 303 00:18:17,300 --> 00:18:19,300 単にRigidbodyを追加するだけです。 304 00:18:19,300 --> 00:18:22,300 そして、箱の着地やプレイヤーの取得を検出する為に 305 00:18:22,300 --> 00:18:24,300 コライダーも追加します。 306 00:18:24,960 --> 00:18:26,960 箱が着陸したら 307 00:18:26,960 --> 00:18:30,510 落下傘をしぼませるステートに遷移します。 308 00:18:30,510 --> 00:18:33,300 他のアニメータと同じ様に 309 00:18:33,300 --> 00:18:34,910 アニメーターはオブジェクトのステートを管理しています。 310 00:18:34,910 --> 00:18:36,910 デフォルトではfloatDownステートですが 311 00:18:36,910 --> 00:18:42,910 LandトリガーがTrueになると着陸のステートに切り替わります。 312 00:18:43,970 --> 00:18:47,380 この処理はスクリプトのonTriggerEnter関数で実行しています。 313 00:18:47,380 --> 00:18:49,730 タグで地面を見て地面かどうかを判断しています。 314 00:18:49,730 --> 00:18:53,820 箱を親オブジェクトからデタッチし、 315 00:18:53,820 --> 00:18:55,090 Rigidbodyを追加します。 316 00:18:55,090 --> 00:18:57,490 それにより、地形の影響を受け 317 00:18:57,490 --> 00:19:00,620 斜面に着陸した場合でも正しい角度で停止します。 318 00:19:00,620 --> 00:19:03,670 さて、爆弾を見てみましょう。 319 00:19:03,670 --> 00:19:05,670 爆弾を取得する処理は 320 00:19:05,670 --> 00:19:08,470 箱に付属したBombPickupスクリプトで行われます。 321 00:19:08,470 --> 00:19:11,050 爆弾を拾うと、箱を消して 322 00:19:11,050 --> 00:19:14,050 プレイヤーに付属したLayBombsスクリプト内の 323 00:19:14,050 --> 00:19:17,050 爆弾を持つ数を加算します。 324 00:19:17,550 --> 00:19:19,550 LayBombsのスクリプトは 325 00:19:19,550 --> 00:19:22,550 プレイヤーが爆弾を持っているかどうかをチェックして 326 00:19:22,550 --> 00:19:24,550 BombのPrefabを生成します。 327 00:19:27,420 --> 00:19:32,950 BombのPrefabはBombDetonationというcoroutineで 328 00:19:32,950 --> 00:19:36,000 待ってExplode関数を呼び出します。 329 00:19:36,790 --> 00:19:39,540 Explode関数は様々な動作があります。 330 00:19:39,540 --> 00:19:41,540 まず、他の爆弾が出現できる様にするため 331 00:19:41,540 --> 00:19:43,790 変数bombLaidをリセットします。 332 00:19:43,790 --> 00:19:46,790 そしてアイテム管理に新しい箱が追加可能な事を通知し 333 00:19:46,790 --> 00:19:49,790 範囲内にいる全ての敵を倒します。 334 00:19:50,510 --> 00:19:53,050 最後の部分がどのような働きをするのか注目して下さい。 335 00:19:53,050 --> 00:19:55,050 残りHPに関係なく全ての敵を倒すために 336 00:19:55,050 --> 00:19:57,180 Physics.OverlapCircleAllを使って 337 00:19:57,180 --> 00:20:02,970 全てのEnemyタグが付けられたオブジェクトを取得します。 338 00:20:03,470 --> 00:20:08,610 foreachループで見つかった全ての敵のHPを0にして 339 00:20:08,610 --> 00:20:13,660 爆弾から敵の方向に吹き飛ばします。 340 00:20:16,300 --> 00:20:18,530 ループが終わったら 341 00:20:18,530 --> 00:20:21,380 エフェクトを再生し 爆発の効果音を再生して 342 00:20:21,380 --> 00:20:24,380 爆弾を消去します。 343 00:20:26,870 --> 00:20:29,250 爆発には2つの要素で構成されています。 344 00:20:29,250 --> 00:20:32,250 主な部分は、一時的に登場して消える丸です。 345 00:20:33,580 --> 00:20:35,580 2番目の部分はロケットの爆発のスプライトを再利用した 346 00:20:35,580 --> 00:20:38,580 星のパーティクルです。 347 00:20:42,260 --> 00:20:44,260 効率よくこのパーティクルを使用するために 348 00:20:44,260 --> 00:20:46,260 常にシーンに配置しておき 349 00:20:46,260 --> 00:20:51,260 表示させたいタイミングで表示位置に動かして再生します。 350 00:20:52,510 --> 00:20:54,510 メモリにパーティクルを常駐させる事で効率が良くなります。 351 00:20:54,510 --> 00:20:56,510 これは、プレイヤーは1つしか爆弾を持てない、 352 00:20:56,510 --> 00:21:00,510 つまり爆発も1つしか表示されないので出来る事です。 353 00:21:01,010 --> 00:21:04,660 パーティクルを常駐させておくことで 354 00:21:04,660 --> 00:21:12,790 毎回パーティクルのインスタンスを生成して削除するよりも効率的です。 355 00:21:15,710 --> 00:21:18,610 ですが、ロケットの爆発は一度にたくさん出る事があるので 356 00:21:18,610 --> 00:21:21,610 毎回生成と削除する事が必要です。 357 00:21:22,110 --> 00:21:26,110 プレイヤーが敵を倒してポイントを得る処理を見てみましょう。 358 00:21:26,610 --> 00:21:28,430 これは2つのパーツでできています。 359 00:21:28,430 --> 00:21:31,660 プレイヤーが100ポイントを獲得した表示と 360 00:21:31,660 --> 00:21:34,660 画面の上に表示されているスコアーが加算されてゆくUIです。 361 00:21:35,520 --> 00:21:39,300 得点のアニメーションは1と0のスプライトで構成されています。 362 00:21:40,190 --> 00:21:42,870 空のオブジェクトの子として配置し 363 00:21:42,870 --> 00:21:47,030 アニメーションが終わると簡単なスクリプトで 364 00:21:47,030 --> 00:21:49,180 シーンから削除されます。 365 00:21:49,180 --> 00:21:52,180 アニメーションの最後にイベントを追加し 366 00:21:52,180 --> 00:21:55,180 スクリプトの削除関数を呼び出します。 367 00:22:06,140 --> 00:22:09,700 ScoreUIは、カスタムフォントと 368 00:22:09,700 --> 00:22:11,700 プレイヤーの得点を管理するスクリプト付属された 369 00:22:11,700 --> 00:22:13,700 シンプルなGUIコンポーネントです。 370 00:22:13,700 --> 00:22:16,750 Scoreはパブリック変数です。 371 00:22:16,750 --> 00:22:18,980 なので敵が倒された時、 372 00:22:18,980 --> 00:22:20,980 Enemyのスクリプトからポイントを追加する事ができます。 373 00:22:20,980 --> 00:22:24,980 さて、今度は敵の話です。 詳細を見てみましょう。 374 00:22:25,480 --> 00:22:28,260 このゲームには2種類の敵が登場します。 375 00:22:28,260 --> 00:22:30,850 緑のナメクジモンスターと 376 00:22:30,850 --> 00:22:33,850 宇宙船に乗った宇宙人です。 377 00:22:34,560 --> 00:22:40,560 挙動はほぼ同じなので同じスクリプトを使い回し、 378 00:22:40,560 --> 00:22:44,560 Inspectorから移動速度とHPを調整して差を付けています。 379 00:22:46,630 --> 00:22:49,090 各敵はそれぞれのWalkアニメーションがあります。 380 00:22:49,090 --> 00:22:51,090 ナメクジには動く尾があり 381 00:22:51,090 --> 00:22:54,440 宇宙船の敵は行ったり来たりします。 382 00:22:55,990 --> 00:22:57,990 ナメクジの尾の部分は 383 00:22:57,990 --> 00:23:01,990 スプライトインポータで独立したパーツとしてインポートしました。 384 00:23:01,990 --> 00:23:04,430 なので、尾の部分を独立して動かす事ができ、 385 00:23:04,430 --> 00:23:07,470 スプライト全体が伸び縮みししないようになっています。 386 00:23:07,470 --> 00:23:09,470 Pivotを右にする事で 387 00:23:09,470 --> 00:23:14,120 そこから尾が伸び縮みするアニメーションをつけます。 388 00:23:16,470 --> 00:23:19,910 まぶたを上下に動かして 389 00:23:19,910 --> 00:23:21,910 Z値でスプライトがソートされるようにし 390 00:23:21,910 --> 00:23:25,850 目がまぶたの下に表示されるようにします。 391 00:23:28,860 --> 00:23:31,260 次の敵はかなりシンプルです。 392 00:23:31,260 --> 00:23:34,040 行ったり来たりを繰り返すアニメーションにします。 393 00:23:35,790 --> 00:23:39,790 敵の動きには、Rigidbodyの速度をセットします。 394 00:23:41,220 --> 00:23:43,880 宇宙船が障害物、例えば壁等への衝突は 395 00:23:43,880 --> 00:23:47,820 ある点がコライダーと重なっているかどうかを 396 00:23:47,820 --> 00:23:51,310 Physics.OverlapPoint関数を用いて検知します。 397 00:23:51,310 --> 00:23:53,850 障害物、このステージ両端のタワーは 398 00:23:53,850 --> 00:23:55,850 障害物としてタグが設定されています。 399 00:23:55,850 --> 00:23:59,160 衝突を検知するとFlip関数を呼び出して 400 00:23:59,160 --> 00:24:03,760 敵のXスケールを反対にして反対方向に向かわせます。 401 00:24:04,070 --> 00:24:06,070 敵を倒す判定のために、 402 00:24:06,070 --> 00:24:11,030 ロケットが敵に当たる度にHurt関数を呼び出します。 403 00:24:14,960 --> 00:24:18,960 この関数の内部では、敵のHPを1づつ下げています。 404 00:24:19,210 --> 00:24:23,210 FixedUpdate関数の中で敵のHPを監視しており、 405 00:24:23,210 --> 00:24:27,120 0になっている場合はDeath関数が呼び出されます。 406 00:24:31,220 --> 00:24:33,910 敵が死亡する時には様々な処理が実行されます。 407 00:24:33,910 --> 00:24:39,910 まず、2Dのキャラクターの全てのスプライトを非表示にします。 408 00:24:40,940 --> 00:24:42,940 これは、アニメーションのためにある複数のスプライトを 409 00:24:42,940 --> 00:24:46,940 1つの死亡したキャラクターのスプライトに差し替えたいからです。 410 00:24:47,740 --> 00:24:51,740 メインのSprite RendererにdeadEnemyのスプライトを設定します。 411 00:24:54,160 --> 00:24:58,160 Scoreスクリプトのパブリック変数に対し スコアを加算します。 412 00:24:58,160 --> 00:25:00,740 敵の死亡のビジュアルをわかりやすくするため 413 00:25:00,740 --> 00:25:03,530 Rigidbodyにトルクを追加して回転させます。 414 00:25:04,440 --> 00:25:08,440 背景を突き抜けて川に落下させたいので 415 00:25:08,880 --> 00:25:10,880 すべてのコライダーを探して 416 00:25:10,880 --> 00:25:13,580 IsTriggerパラメーターをTrueにします。 417 00:25:13,580 --> 00:25:17,130 これで背景のコライダーを突き抜ける事になります。 418 00:25:17,410 --> 00:25:21,050 死亡時に再生するオーディオクリップ中の1つを選び再生し 419 00:25:21,050 --> 00:25:25,050 前述の得点表示アニメーションを再生します。 420 00:25:27,870 --> 00:25:29,870 敵をシーンから削除するため、 421 00:25:29,870 --> 00:25:31,870 KillTriggerオブジェクトを使います。 422 00:25:31,870 --> 00:25:34,760 これは先ほど説明した通り、 水しぶきをあげオブジェクトを消去する機能を持ちます。 423 00:25:34,760 --> 00:25:36,760 プレイヤー以外のオブジェクトが触ると 424 00:25:36,760 --> 00:25:39,950 水しぶきのエフェクトを表示して オブジェクトを削除します。 425 00:25:39,950 --> 00:25:42,950 効果音は水しぶきエフェクトが表示される時に 426 00:25:42,950 --> 00:25:45,950 付属しているAudio Clipが同時に再生されます。 427 00:25:45,950 --> 00:25:47,950 なので、オブジェクトを生成するだけで 428 00:25:47,950 --> 00:25:50,630 効果音も鳴るようになっています。 429 00:25:55,150 --> 00:25:57,150 動的なオブジェクトを追加し 430 00:25:57,150 --> 00:26:01,150 背景を飾ってステージを完成させましょう。 431 00:26:02,300 --> 00:26:05,700 飛んでいる白鳥と 432 00:26:05,700 --> 00:26:07,120 川岸を走るバスとタクシーを追加します。 433 00:26:07,120 --> 00:26:12,630 まずは白鳥のスプライトシートをPhotoshopで描いて 434 00:26:12,630 --> 00:26:14,630 InspectorのMultiple Sprite Modeを使ってインポートしました。 435 00:26:16,050 --> 00:26:18,800 この方法では 436 00:26:18,800 --> 00:26:21,800 Unityが全てのコマを選択し自動的にインポートして 437 00:26:21,800 --> 00:26:24,800 アセットのヒエラルキーに追加してくれます。 438 00:26:24,570 --> 00:26:27,270 このコマは連続したアニメーションのセットなので、 439 00:26:27,270 --> 00:26:29,270 全てのコマをシーンにドラッグするだけで 440 00:26:29,270 --> 00:26:32,340 Unityが自動的にアニメーションさせてくれます。 441 00:26:32,340 --> 00:26:35,310 ね、簡単でしょ? 442 00:26:35,310 --> 00:26:37,750 白鳥は背景に追加します。 443 00:26:37,750 --> 00:26:40,160 速度を与えて画面中を動けるように 444 00:26:40,160 --> 00:26:43,160 Rigidbody2Dを追加します。 445 00:26:43,360 --> 00:26:47,330 バスとタクシーのように、白鳥もPrefabです。 446 00:26:49,250 --> 00:26:51,250 バスとタクシーのPrefabには、 447 00:26:51,250 --> 00:26:54,250 Sprite Importerで車体とタイヤを分割して 448 00:26:54,250 --> 00:26:57,250 シンプルなアニメーションを生成します。 449 00:26:58,390 --> 00:27:01,790 これらにもRigidbody2Dを追加して 450 00:27:01,790 --> 00:27:03,790 速度の追加で画面内を動かす事ができます。 451 00:27:07,270 --> 00:27:10,270 白鳥、バス、タクシー 452 00:27:10,270 --> 00:27:12,270 この3種のオブジェクトの生成を 453 00:27:12,270 --> 00:27:14,270 管理するスクリプトを作成してあります。 454 00:27:14,270 --> 00:27:17,610 BackgroundPropsSpawnerスクリプトは 455 00:27:18,610 --> 00:27:21,830 頻度、速度、そして最初の位置を管理しています。 456 00:27:21,830 --> 00:27:26,520 3種のオブジェクトに同じスクリプトを使うことができます。 457 00:27:26,520 --> 00:27:28,520 生成するPrefabとプロパティを変更します。 458 00:27:30,520 --> 00:27:35,850 詳細は、スクリプトのコメントをご覧ください。 459 00:27:36,170 --> 00:27:40,400 最後に、動いている雲、川の流れ、そして霧を追加しました。 460 00:27:41,320 --> 00:27:44,520 親オブジェクトに2つのスプライトを持たせ、 461 00:27:44,520 --> 00:27:48,000 ゆっくりと横に動かします。 462 00:27:50,000 --> 00:27:54,650 アニメーションはループで動き続けます。 463 00:27:59,180 --> 00:28:02,030 以上が、私たちがどのようにしてこのゲームを作ったか、の全てです。 464 00:28:02,030 --> 00:28:05,030 このビデオが2Dゲームの作り方の参考になれば嬉しく思います。 465 00:28:05,510 --> 00:28:07,510 将来的には、より基本的なプロジェクトと 466 00:28:07,510 --> 00:28:08,970 チュートリアルをお届けしたいと考えています。 467 00:28:08,970 --> 00:28:12,680 私達は、Unity4.3についての感想と 468 00:28:12,680 --> 00:28:14,680 あなたの作る素晴らしい2Dゲームが本当に楽しみです。 469 00:28:14,950 --> 00:28:16,480 それでは、ご清聴ありがとうございました!