プレイヤーから弾を撃つ

確認済のバージョン: 5.5

-

難易度: 初級

前章ではプレイヤーが移動するところまで出来ました。 次はプレイヤーが自動で弾を連射するようにします。

親子関係


図3.1:

Unityでは、「親子関係」という言葉を使います。これはゲームオブジェクト同士の関係性を表しています。 普段、ゲームオブジェクトは図3.1のように縦に並びます。これは同じ位置にゲームオブジェクトが存在することになり、それぞれは独立しています。


図3.2:


図3.2はGameObject 1が親GameObject 2が子として関係を持ちます。これは子であるGameObject 2が、親のGameObject 1の影響を受けることになります。例えば親が移動・回転を行えば子も同じように移動・回転を行います。

3.1 プレイヤーの弾を作成する

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


図3.3:

今回は名前をBulletとしました。


図3.4:

3.2 プレイヤーの弾を動かす

ゲームを再生したら勝手に上に飛んで行く弾を作成しましょう。


図3.5:

親となるPlayerBulletの作成

空のゲームオブジェクトを作成します。作成した空のゲームオブジェクトの名前をPlayerBulletとしてください。

空のゲームオブジェクトを作る

空のGameObjectはメニューの[Game Object] -\> [Create Empty]から作成できます。 空のGameObjectはTransformコンポーネントのみがアタッチされている状態のことを指します。


図3.6:

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

PlayerBulletゲームオブジェクトのインスペクター
図3.7: PlayerBulletゲームオブジェクトのインスペクター

Player Bulletの位置はプレイヤーの中心位置にしましょう。

> 中心位置はPlayerとPlayerBulletを(0,0,0)の位置に移動することで調整しやすくなります。


図3.8:

Bulletを複製します。ヒエラルキーウィンドウにあるBulletゲームオブジェクトの上で右クリックをして「Duplicate」を選択します。

それぞれのBulletを以下のように配置します。 左のBullet: X -0.14 Y 0 Z 0 右のBullet: X 0.14 Y 0 Z 0

そして2つのBulletをPlayerBulletの子要素となるようにドラッグ&ドロップしましょう。

最後に、PlayerBulletをPrefab化しましょう。

Prefabsフォルダを作成してください
図3.9: Prefabsフォルダを作成してください

弾を動かす

次にBullet.csファイルをScriptsフォルダの中に作成します。プレイヤーの移動と同じようにGetComponent<Rigidbody2D>().velocityを使って弾を移動させます。今回は速度ベクトルは1度のみ変更すれば良いのでStartメソッド内で速度ベクトルの代入を行いましょう。

Bullet.cs


using UnityEngine;

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

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


Bullet.csをPlayerBulletにアタッチします。Bulletではないので注意してください


図3.10:

この段階でゲームを再生してみましょう。 再生と同時に弾が上に飛んでいきましたか?


図3.11:

PlayerBulletのPrefabの更新を行いましょう。Applyを必ず押してください。


図3.12:

3.3 プレイヤーから弾を発射する

作成したPlayerBulletのPrefabを使ってスクリプト側からゲームオブジェクトを作成し、弾を発射します。 その前に、シーン上にあるPlayerBulletを削除しましょう。ヒエラルキーウィンドウにあるPlayerBulletゲームオブジェクトの上で右クリックをして「Delete」を選択します。


図3.13:

Startメソッドをコルーチンとして呼び出し、0.05秒ごとに弾を撃つようにしてみましょう。

コルーチン (Coroutine)

時間のかかる処理や、何かを待機するような処理をUpdateメソッド内で行うと、その処理が終わるまでゲームの進行がストップしてしまいます。 このような処理は数秒待機したり、特定の処理が終わるまで待機することが可能なコルーチンを利用します。 詳しくはドキュメントのCoroutinesを御覧ください。

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 ("Horizontal");

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

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

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


public GameObject bullet;というようにpublicで変数を宣言すると、インスペクター上にゲームオブジェクトを格納するための場所が表示されます。 ここにPlayerBulletのPrefabを格納しましょう。


図3.14:

さて、ゲームを再生してみましょう。弾が発射されていますか?


図3.15:

3.4 スプライトの描画順

弾が発射されるようになりましたが、ここで気になる点があります。弾がプレイヤーの上に表示されてしまっています。これでは発射口からたまが出ていることにならず違和感を覚えます。

弾がプレイヤーの上に表示されている状態
図3.16: 弾がプレイヤーの上に表示されている状態

弾がプレイヤーの下に表示されている状態
図3.17: 弾がプレイヤーの下に表示されている状態

Sorting Layer (ソーティングレイヤー)

スプライトの描画順を変更するにはSorting Layerを使用します。 Edit -&gt; Project Settings -&gt; Tags and Layersを選択してください。

+」ボタンを押してレイヤーを追加します。レイヤー名がBulletPlayerの2つを作成します。 必ず順序は上からDefault、Bullet、Playerにしてください。この順序が描画順になります。

次に、先ほど追加したSorting Layerを適用します。 PlayerBulletブレハブの中のBulletを2つ選択し、インスペクターにあるSorting LayerをDefaultからBulletへ変更します。

Playerゲームオブジェクトを選択し、インスペクターにあるSorting LayerをDefaultからPlayerへ変更します。

ゲームを再生してみましょう。弾がプレイヤーの下に描画されるようになったはずです。 最後に、PlayerのPrefabを更新しましょう。