Unity 5で 2Dシューティングのチュートリアルを行う際の注意点(第04回)
Unity公式チュートリアル 2Dシューティング
第04回 敵を作成しよう
上記チュートリアルで、私がつまずいたところ、初心者がつまずきそうなところをピックアップして解説します。
4.1 スクリプトの使い回し
新たにSpaceship.csをScriptsフォルダの中に作成します。プレイヤーと敵で共通するであろう部分をSpaceship.csに実装していきます。
Projectタブ内のScriptsフォルダを右クリックし、Create -> C# Script を選択後、追加されたファイルをSpaceshipにリネームします。
リネームまで一気にやらないと、生成されたファイルのクラス名がデフォルトの名前になってしまうので注意しましょう。
リネーム後、Spaceshipをダブルクリックし、MonoDevelopでSpaceship.csを開き、編集します。
スクリプト内を全部チュートリアルのものに置き換えてしまえば問題はないです。
また、ソースを置換後、「rigidbody2D.velocity」の「velocity」が赤くなりますが、Ctrl+Sで保存後、Unityに戻ると表示されるダイアログの「Go Ahead!」をクリックすれば自動修正してくれます。
次はPlayer.csの共通化された部分を修正していきます。
Startメソッドの中でGetComponentを使いSpaceshipコンポーネントを取得しています。
ProjectタブのScriptsフォルダ配下にあるPlayerをダブルクリックし、MonoDevelopでSpaceship.csを編集します。
ソースの中身を置き換えたら、Ctrl+Sで保存し、Unity画面に戻りましょう。
今回の修正内容は以下のとおりです。
Start()
・弾の生成処理をSpaceship内に実装した関数で行うように変更
・Spaceshipの変数を使って弾のショット間隔を設定するよう変更
Update()
・移動処理をSpaceship内に実装したMove関数で行うよう変更
Spaceship.csをPlayerゲームオブジェクトにアタッチしたら、インスペクター側でSpeedを5、Shot Delayを0.05、BulletをPlayerBulletのPrefabに再設定しましょう。
Projectタブ内にあるScriptフォルダ配下のSpaceshipを、Hierarchyタブ内のPlayerにドラッグ&ドロップしてアタッチします。
アタッチ後、Hierarchyタブ内のPlayerを選択してInspectorを表示させると、その一番下にSpaceship(Script)が追加されています。
そこでSpeed/Shot Delayを書き換え、Bulletの枠にProjectタブ内のPrefabsフォルダ配下にあるPlayerBulletをドラッグ&ドロップして設定します。
4.3 敵専用のスクリプトを書く
敵の移動
新たにEnemy.csをScriptsフォルダの中に作成します。
Projectタブ内のScriptsフォルダを右クリックし、Create -> C# Script を選択後、追加されたファイルをEnemyにリネームします。
その後、Enemyをダブルクリックで開き、MonoDevelop上でソースを置き換えます。
ソースは丸ごと置き換えてしまって構いません。
置換後、Ctrl+Sで保存したら、Unity画面に戻りましょう。
EnemyゲームオブジェクトにEnemyコンポーネントをアタッチし、Spaceshipのspeedを0.5にしましょう。
Projectタブ内のScriptフォルダ配下にあるEnemyを、Hierarchyタブ内のEnemyにドラッグ&ドロップしてアタッチします。
アタッチ後、Hierarchyタブ内のEnemyを選択してInspectorを表示させると、その一番下にEnemy(Script)が追加されているのが確認できます。
Enemy(Script)の上側には、先ほどアタッチしたSpaceship(Script)も表示されているので、そこでspeedを修正します。
弾の作成
敵の弾となるBullet_1スプライトをシーンビューへドラッグ&ドロップします。
図4.5:
名前をEnemyBulletとします。
図4.5のとおり、ProjectタブのSprite/Bullet/Bullet配下にあるBullet_1スプライトをシーンビューへドラッグ&ドロップすると、Hierarchyタブ内にBullet_1ゲームオブジェクトが生成されます。
これを「EnemyBullet」にリネームします。
リネームする時は、Bullet_1をクリックして選択状態にした後、もう一度クリックするか、F2キーを押すとリネームできます。
そして、Bullet.csとRigidbody2Dをアタッチしましょう。
まず、Projetタブ内のSpriptsフォルダ配下にあるBulletを、Hierarchyタブ内のEnemyBulletにドロップしてアタッチします。
次に、EnemyBulletをクリックして選択後、Inspector内の一番下に表示される「Add Component」をクリックして、Physics 2D > Rigidbody 2Dと選択し、Rigidbody2Dをアタッチします。
BulletのSpeedを2に、Rigidbody2DのGravity Scaleを0にしてください。
Inspector内に表示されているBulletとRigidbody2Dの中のそれぞれの値を修正します。
最後にPrefabとして保存を行い、EnemyにアタッチされているSpaceshipコンポーネントのBulletにEnemyBulletプレハブを格納してください。
まず、Hierarchyタブ内のEnemyBulletを、Projectタブ内のPrefabsフォルダにドラッグ&ドロップしてPrefabとして保存します。Prefabs配下にEnemyBulletが表示されます。
次に、Hierarchyタブ内のEnemyBulletをクリックして選択し、Deleteキーを押して削除します。
最後に、Hierarchyタブ内のEnemyをクリックし、Inspectorに表示される Spaceship(Script)内のBulletの枠内に、Projectタブ内のPrefabs配下のEnemyBulletをドラッグ&ドロップして格納します。
これで、チュートリアルの図4.7のようになるはずです。
弾の発射
ShotPositionの作成
敵の子要素として新たに空のGameObjectを作成し、名前をShotPositionとします。これを合計3つ作成しましょう。
Hierarchy内のEnemyを右クリックしてCreate Emptyを選択し、空のGameObjectを追加します。これをShotPositionにリネームします。
作成したShotPositionを右クリックし、Duplicateで複製し、ShotPositionにリネームします。
さらにもうひとつ複製し、3つのShotPositionを作ります。
表4.1: TransformのRotationを変更します
ゲームオブジェクト名 X Y Z
ShotPosition(その1) 0 0 160
ShotPosition(その2) 0 0 180
ShotPosition(その3) 0 0 200
1つめのShotPositionをクリックし、Inspectorに表示されたTranform内のRotationのZ値を160に書き換えます。
2つめ、3つめも同様に書き換えます。
ShotPositionから弾を撃つ
先ほど作成したShotPositionをスクリプト側で取得してみます。Startメソッドをコルーチンに変更して、プレイヤーのようにwhile文の中で弾を撃ちます。
Projectタブ内Scriptsフォルダ配下のEnemyをダブルクリックし、Emeny.csの内容をチュートリアルのソースで置き換えます。
変更内容は以下の通りです。
・Start関数をコルーチン化
・永久ループの中で、Ememy配下のShotPositionのTransform値を取得し、その値で弾を撃ち、数秒ウェイトする処理を追加(コルーチンなのでこの処理がゲーム進行と平行してなんども繰り返される)
EnemyゲームオブジェクトのShot Delayを0.3にします。
Hierarchyタブ内のEnemyをクリックし、Inspectorに表示されるSpaceship(Script)内のShot Delay値を書き換えます。
弾を撃たない敵を作る
Spaceship.csに変数の追加
弾を撃つか撃たないかの状態をcanShotというbool型の変数で保持するようにします。
Projectタブ内のScriptsフォルダ配下にあるSpaceshipをダブルクリックし、MonoDevelopでSpaceship.csの内容をチュートリアルのソースで置き換えます。
もしくは、変更点である「public bool canShot;」の部分のみをソースに追加してもOKです。
全てを置き換えた時は「rigidbody2D.velocity 」がエラーとなるので、Ctrl+Sで保存してUnityに戻った時に「Go Ahead!」をクリックし、ソースを自動修正させましょう。
Enemy.csの修正
弾を撃つ処理としてStartメソッドをコルーチンとして実行していますが弾を撃つ必要がない時はyield break;を使用してコルーチンを終了させます。
Projectタブ内のScriptsフォルダ配下にあるEnemyをダブルクリックし、MonoDevelopでEnemy.csの内容をチュートリアルのソースで置き換えます。
変更点は、「canShotがfalseの場合、ここでコルーチンを終了させる」ための処理の部分だけなので、ここだけ追加でも構いません。
ソースを修正したら、Ctrl+Sで保存し、Unity画面に戻りましょう。
スクリプトでtrue、インスペクターでチェックを付けると弾を撃てるようになります。
HierarchyタブのEnemyを選択し、Inspectorの一番下に表示されるSpaceship(Script)の中に、「Can Shot」というチェックボックスが追加されます。
ここを変更することで、敵が弾を撃つかどうかを設定できます。
最後に、シーンとプレハブをきちんと更新しましょう!
Hierarchyタブ内のPlayerを選択し、Inspectorの上の方に表示されている「Prefab」横の「Apply」を押して、プレハブを更新しましょう。
同様にEnemyも更新します。
シーンの更新?というのはよくわかりません。
上書き保存しろと言われている気がするので、とりあえずCtrl+Sでシーンを上書き保存しておきましょう。