[Unity] 2Dシューティングゲームを作る 2 [チュートリアル]

株式会社プライムストラクチャーのエンジニアのSayaです。

今回は前回に引き続き、 Unity の公式から 2D のシューティングゲームを作るチュートリアルを参考にしながら簡潔にまとめてみたいと思います。

用語

Rigidbody 2D クラス

2D で物理挙動を行うために必要なクラスです。
重力や物体の移動などの物理挙動はこのクラスを介して行われます。

Input クラス

キーボードや JoyStick といった、コントローラーの全ての入力を処理するためのクラスです。
モバイル端末などでは加速度センサーやジャイロにもアクセスすることが出来ます。

アタッチ

ゲームオブジェクトにコンポーネントを取り付けることをアタッチすると言います。

プレハブからゲームオブジェクトを作成

Project ビューの Prefabs フォルダに入っている Player プレハブを Scene ビューへドラッグ&ドロップしてゲームオブジェクトを作ります。

Player に RigidBody 2D をアタッチ

Player のゲームオブジェクトに Rigidbody 2D をアタッチします。
Hierarchy ビューから Player を選択して Inspector の一番下にある Add Component をクリックして RigidBody 2D を検索してアタッチします。

そして Gravity Scale の項目を今回は重力を使わないので 0 にします。

また同じく Inspector の項目で既にアタッチされている AnimatorApply Root Motion にチェックが入っている場合は外します。
これは 3D モデルに対してアニメーションを制御するもので、今回は 2D モデルを使用するので不具合を回避するためにチェックを外します。

Player にスクリプトをアタッチ

スクリプトファイルの作成

上部メニューバーの Assets -> Create -> C# Script と進んで新規スクリプトを作成します。
ファイル名は Player とします。

Assets フォルダ配下に Scripts フォルダを作成して上記のスクリプトを格納します。

スクリプトを書く

作成した Player スクリプトをダブルクリックしてエディタを開きます。
Visual Studio が開くはずですが、Monodevelop が開く場合もあります。

まずプレイヤーが矢印キーで移動出来るようにスクリプトを記述します。

以下のコードを Player.cs に実装します。

Player.cs
using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour
{
  // 移動スピード
  public float speed = 5;

  void Update ()
  {
    // 右・左
    float x = Input.GetAxisRaw ("Horizontal");

    // 上・下
    float y = Input.GetAxisRaw ("Vertical");

    // 移動する向きを求める
    Vector2 direction = new Vector2 (x, y).normalized;

    // 移動する向きとスピードを代入する
    GetComponent<Rigidbody2D>().velocity = direction * speed;
  }
}

  • Input.GetAxisRaw
    矢印キーのを押せば -1を押せば 1、何も押さなければ 0 を取得できます。
    アナログスティックのような不完全な押し方が存在する場合は -1 から 1 の間の値も検出できる Input.GetAxis(string axisName) を使用します。

キー入力によって得られるプレイヤーの移動する向きと速度 (速度ベクトル)を rigidbody2D.velocity に代入します。

Player にスクリプトをアタッチする

Project ビューの Scripts フォルダに入っている Player スクリプトを Project ビューの Assets / Prefabs / Player にドラッグ&ドロップしてアタッチします。

Main Camera の調整

Hierarchy から Main camera を選択して、Inspector から Camera の項目で Projection が Orthographic になっていることを確認したら Size を 3 にします。

これにより見える範囲が調整出来ます。

シーンを保存する

Command + S キーか、上部メニューバーの File -> Save Scenes と進んでシーンを保存します。

親子関係

Unity には親子関係の概念があります。
親子関係を作ると親要素の動作が子要素にも受け継がれます。
例えば親要素が移動・回転を行うと子要素も同じように移動・回転を行うなどです。

Player の弾を作成する

  • プレイヤーの弾となる Bullet_0 を Scene ビューへドラッグ&ドロップします。

  • Hierarchy 上の Bullet_0 の名前を Bullet に変更します。

  • Transform コンポーネントのみがアタッチされているゲームオブジェクトを空のゲームオブジェクトと呼びます。
    上部メニューバーから GameObject -> Create Empty を選択して空のゲームオブジェクトを作成します。
    作成した空のゲームオブジェクトの名前をPlayerBulletとします。

  • PlayerBulletに「Rigidbody2D」をアタッチし、Gravity Scaleを0にします。

  • Player と PlayerBullet の位置を Transform コンポーネントで X:0, Y:0, Z:0 に設定します。

  • Bulletを複製します。Hierarchy から Bullet を右クリックをしてDuplicateを選択します。

  • 2 つ存在する Bullet の片方を Transform から X:-0.14, Y:0 , Z:0 に設定し、もう片方を X:0.14, Y:0, Z:0 に設定します。

  • 2つの Bullet を PlayerBullet の子要素となるようにドラッグ&ドロップします。
    すると以下の画像のように親子関係が作られます。

この画像では左に配置した Bullet を LeftBullet, 右に配置した Bullet を RightBullet と名前を変えています。

  • PlayerBullet をプレハブ化します。親要素の PlayerBullet を Assets / Prefabs フォルダにドラッグ&ドロップします。

弾を動かす

弾の実装

Project ビューの Create ボタンで C# Script を選択して Bullet.cs ファイルを作成し Scripts フォルダに格納します。

作成した Bullet.cs をダブルクリックで開きます。

コードを以下のように記述します。

“`Bullet.cs
using UnityEngine;

public class Bullet : MonoBehaviour
{
public int speed = 10;

void Start ()
{
GetComponent<Rigidbody2D>().velocity = transform.up.normalized * speed;
}
}

&lt;br /&gt;保存したら Bullet.cs を Hierarchy 上の PlayerBullet へドラッグ&amp;ドロップでアタッチし、 PlayerBullet の Inspector 上の Prefab から **Apply** ボタンを押します。

これで Unity の&lt;u&gt;再生ボタン&lt;/u&gt;を押すと Player から弾が発射されるのが確認出来ます。
弾が早すぎて見えない場合は、PlayerBullet にアタッチされている Bullet.cs の Speed の値を 10 から **2** ぐらいにすると見えるようになると思います。

### Player から弾を発射する
作成した PlayerBullet の Prefab を使ってスクリプト側からゲームオブジェクトを作成し、弾を発射出来るようにします。
その前に、シーン上にある PlayerBullet を削除します。
Hierarchy 上の PlayerBullet を右クリックで **Delete** します。

そして Player.cs の中身を以下のように書き替えます。

```Player.cs
using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour
{
  // 移動スピード
  public float speed = 5;

  // PlayerBulletプレハブ
  public GameObject bullet;

  // Startメソッドをコルーチンとして呼び出す
  IEnumerator Start ()
  {
    while (true) {
      // 弾をプレイヤーと同じ位置/角度で作成
      Instantiate (bullet, transform.position, transform.rotation);
      // 0.05秒待つ
      yield return new WaitForSeconds (0.05f);
    }
  }

  void Update ()
  {
    // 右・左
    float x = Input.GetAxisRaw (&quot;Horizontal&quot;);

    // 上・下
    float y = Input.GetAxisRaw (&quot;Vertical&quot;);

    // 移動する向きを求める
    Vector2 direction = new Vector2 (x, y).normalized;

    // 移動する向きとスピードを代入する
    GetComponent&lt;Rigidbody2D&gt;().velocity = direction * speed;
  }
}

Prefabs フォルダに入っている Player プレハブの Inspector からスクリプトがアタッチされていることを確認し、Bullet の None 部分に PlayerBullet をドラッグ&ドロップで指定します。

これで再生ボタンを押すと Player から弾が発射されます。

スプライトの描画順を変える

弾が発射されるようになりましたが、今は Player の上から重なるように PlayerBullet が描画されています。
Player の発射口から弾が発射されるようにスプライトの描画順を変えます。

スプライトの描画順を変更するには Sorting Layer を使用します。
Unity 上部のメニューバーから Edit -> Project settings -> Tags and Layers を選択します。

Sorting layers の項目を展開して Layer 0 が Default, Layer 1 が Bullet, Layer 2 がPlayer になっていることを確認します。

次に Prefabs の中の PlayerBullet を展開して 2 つの Bullet を選択します。

Inspector 画面から Sprite Renderer の Sorting Layer の項目を Default から Bullet に変更します。

同様に Prefabs のPlayer も Inspector から Sorting Layer を Player に指定します。

これで再生ボタンを押すと、Player に弾が重なることなく発射口から弾が発射されるようになりました。

続く

参考文献

2Dシューティング – Unity
プレイヤーの移動 – Unity
プレイヤーから弾を撃つ – Unity