隕石と背景~横スクロールシューティング④

Unity

●はじめに

2D横スクロールシューティング作成の4回目になります。
アセットストアで無料公開されている「Warped Space Shooter」をお借りして作成しています。

今回は「分裂する隕石と背景」を作成します。
手順が長くなったのと、作成ペースが上がらないのでスコア、敵ウェーブはさらに後回しにします。

 ↑これが完成します。

●隕石作成

▷隕石の作成

隕石のインスペクター情報
隕石を制御

・解説

隕石の画像2枚をそれぞれ配置し、それぞれを敵として作成してプレハブ化します。
衝突させるためHitスクリプトを割り当て、小さい方をEnergy(1)、大きい方をEnergy(5)とします。
Rigidbody2Dを割り当てて重力スケールを(0)、衝突判定を(連続的)とし、CircleCollider2Dを割り当ててトリガーとします。

・隕石小の手順

隕石画像小を配置します。

  1. 「Assets>Space Shooter Assets>Artwork>asteroids>asteroid-small」をシーンにドラッグ&ドロップ
  2. インスペクターの「Transform>スケール」に(4, 4, 0)を入力

Hitスクリプトを割り当てます。

  1. プロジェクトの「Assets>Hit」をヒエラルキーの「asteroid-small」にドラッグ&ドロップ
  2. インスペクターの「Hit (スクリプト)>Energy」に(1)を入力

Rigidbody 2Dを割り当てます。

  1. インスペクターの「コンポーネントを追加」をクリック
  2. 「Physics 2D>Rigidbody 2D」をクリック
  3. インスペクターの「Rigidbody 2D>重力スケール」に(0)を入力
  4. インスペクターの「Rigidbody 2D>衝突判定」を(連続的)に変更

Circle Collider 2Dを割り当てます。

  1. インスペクターの「コンポーネントを追加」をクリック
  2. 「Physics 2D>Circle Collider 2D」をクリック
  3. インスペクターの「Circle Collider 2D>トリガーにする」をチェック

Enemyスクリプトを割り当てます。

  1. プロジェクトの「Assets>Enemy」をヒエラルキーの「asteroid-small」にドラッグ&ドロップ
  2. インスペクターの「Enemy (スクリプト)>速度」に(1)を入力
  3. インスペクターの「Enemy (スクリプト)>Cycle Count」に(0)を入力
  4. インスペクターの「Enemy (スクリプト)>Curve Length」に(0)を入力

プレハブ化します。

  1. ヒエラルキーの「asteroid-small」をプロジェクトの「Assets」にドラッグ&ドロップ

・隕石大の手順

隕石画像大を配置します。

  1. 「Assets>Space Shooter Assets>Artwork>asteroids>asteroid」をシーンにドラッグ&ドロップ
  2. インスペクターの「Transform>スケール」に(4, 4, 0)を入力

Hitスクリプトを割り当てます。

  1. プロジェクトの「Assets>Hit」をヒエラルキーの「asteroid」にドラッグ&ドロップ
  2. インスペクターの「Hit (スクリプト)>Energy」に(5)を入力

Rigidbody 2Dを割り当てます。

  1. インスペクターの「コンポーネントを追加」をクリック
  2. 「Physics 2D>Rigidbody 2D」をクリック
  3. インスペクターの「Rigidbody 2D>重力スケール」に(0)を入力
  4. インスペクターの「Rigidbody 2D>衝突判定」を(連続的)に変更

Circle Collider 2Dを割り当てます。

  1. インスペクターの「コンポーネントを追加」をクリック
  2. 「Physics 2D>Circle Collider 2D」をクリック
  3. インスペクターの「Circle Collider 2D>トリガーにする」をチェック

Enemyスクリプトを割り当てます。

  1. 「Assets>Enemy」をヒエラルキーの「asteroid」にドラッグ&ドロップ
  2. インスペクターの「Enemy (スクリプト)>速度」に(1)を入力
  3. インスペクターの「Enemy (スクリプト)>Cycle Count」に(0)を入力
  4. インスペクターの「Enemy (スクリプト)>Curve Length」に(0)を入力

プレハブ化します。

  1. ヒエラルキーの「asteroid」をプロジェクトの「Assets」にドラッグ&ドロップ

・動作確認

  1. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー開始
  2. 隕石が画面左に向かって移動してくることを確認
  3. 隕石が破壊できることを確認
  4. 隕石に体当たりするとやられることを確認
  5. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー終了

▷隕石をランダムに動かす

プレビューごとに隕石の進む方向が変わる

・解説

隕石をランダムな方向に動かすために変数を追加し、開始時の角度をランダムに設定します。

・手順

ランダム範囲を指定する変数を追加します。

  1. プロジェクトの「Assets>Enemy」をダブルクリック
  2. 「1秒間に進む距離」の下に以下の変数を追加
    public float randomMinDir = 0;  // ランダム方向の最小値
    public float randomMaxDir = 0;  // ランダム方向の最大値

ランダム値を設定する処理を追加します。

  1. Start関数内の最後に以下の処理を追加
        // ランダム範囲が指定されている場合
        if (randomMinDir != randomMaxDir)
        {
            // ランダム方向を設定
            float rotZ = Random.Range(randomMinDir, randomMaxDir);
            transform.rotation = Quaternion.Euler(0, 0, rotZ);
        }

スクリプトを保存してビルドします。

  1. CTRLを押しながらSキーを押してスクリプト保存
  2. Unityエディタをクリックしてビルド

隕石大のランダム方向を指定します。

  1. プロジェクトの「Assets>asteroid-small」をダブルクリック
  2. インスペクターの「Enemy (スクリプト)>Random Max Dir」に(360)を入力
  3. ヒエラルキーの左上にある「<」をクリック
  4. プロジェクトの「Assets>asteroid」をダブルクリック
  5. インスペクターの「Enemy (スクリプト)>Random Max Dir」に(360)を入力
  6. ヒエラルキーの左上にある「<」をクリック

動作を確認します。

  1. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー開始
  2. プレビューを繰り返し、隕石がランダムな方向に動くことを確認
  3. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー終了

▷隕石大を破壊したら隕石小にする

隕石大のインスペクター情報
隕石大を破壊したら隕石小になる

・解説

爆発後に作成するプレハブを指定できるよう、Enemyスクリプトを修正します。

・手順

爆発後に作成するプレハブ一覧を保存するため、変数を追加します。

  1. プロジェクトの「Assets>Hit」をダブルクリック
  2. Start関数の前に以下の変数を追加
    // 爆発後に作成するプレハブの一覧
    public List<GameObject> leavePrefabs;
    // 爆発後に作成したゲームオブジェクトの相対位置
    public List<Vector3> leavePostions;

爆発時にプレハブを残す処理を追加します。

  1. OnTriggerEnter2D内の「自分を削除」する処理の前に以下の処理を追加
            // プレハブを残す
            Vector3 pos = transform.position;
            for (int i = 0; i < leavePrefabs.Count; i++)
            {
                Instantiate(leavePrefabs[i], pos + leavePostions[i], Quaternion.identity);
            }
  1. CTRLを押しながらSキーを押してスクリプト保存
  2. Unityエディタをクリックしてビルド

爆発時に作成するプレハブを割り当てます。

  1. ヒエラルキーの「asteroid」をクリック
  2. プロジェクトの「Assets>asteroid-small」をインスペクターの「Hit (スクリプト)>Leave Prefabs」にドラッグ&ドロップ
  3. プロジェクトの「Assets>asteroid-small」をインスペクターの「Hit (スクリプト)>Leave Prefabs」にドラッグ&ドロップ
  4. プロジェクトの「Assets>asteroid-small」をインスペクターの「Hit (スクリプト)>Leave Prefabs」にドラッグ&ドロップ

爆発時に作成したプレハブの相対位置を設定します。

  1. インスペクターの「Hit (スクリプト)>Leave Positions」右に(3)を入力
  2. インスペクターの「Hit (スクリプト)>Leave Positions」左にある▶をクリックして展開
  3. インスペクターの「Hit (スクリプト)>Leave Positions>要素0>Y」に(0.5)を入力
  4. インスペクターの「Hit (スクリプト)>Leave Positions>要素1」に(-0.3, -0.3, 0)を入力
  5. インスペクターの「Hit (スクリプト)>Leave Positions>要素1」に(0.3, -0.3, 0)を入力

隕石大の変更をプレハブに反映します。

  1. インスペクターの右上にある「オーバーライド」をクリックし、「すべてを適用する」をクリック

プロジェクトを保存して、

  1. CTRLを押しながらSキーを押してプロジェクト保存

動作を確認します。

  1. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー開始
  2. 隕石大を破壊したら隕石小が3つ出現することを確認
  3. 残された隕石小を破壊できることを確認
  4. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー終了

●背景

▷背景表示

ヒエラルキーの状態
BGMのインスペクター情報

・解説

背景スクロールを作成します。

前後関係と多重スクロールを制御しやすいように空オブジェクトで整理し、
空オブジェクトの中に背景画像を配置していきます。

・手順

背景画像を配置するための空オブジェクトを作成します。

  1. ヒエラルキーの左上にある「+」をクリックし、「空のオブジェクトを作成」をクリック
  2. 「background」と入力してENTERを押す
  3. インスペクターの「Transform>位置」に(0, 0, 0)を入力
  4. ヒエラルキーの「background」を右クリックし、「空のオブジェクトを作成」をクリック
  5. 「back」と入力してENTERを押す
  6. インスペクターの「Transform>スケール」に(6.6, 6.6, 1)を入力
  7. ヒエラルキーの「background」を右クリックし、「空のオブジェクトを作成」をクリック
  8. 「stars」と入力してENTERを押す
  9. インスペクターの「Transform>スケール」に(6.6, 6.6, 1)を入力
  10. ヒエラルキーの「background」を右クリックし、「空のオブジェクトを作成」をクリック
  11. 「planet」と入力してENTERを押す
  12. インスペクターの「Transform>スケール」に(6.6, 6.6, 1)を入力

最も奥の背景画像を表示します。

  1. プロジェクトの「Assets>Space Shooter Assets>Artwork>background>bg-back」をヒエラルキーの「background>back」にドラッグ&ドロップ
  2. インスペクターの「Transform>スケール」に(1, 1, 1)を入力
  3. インスペクターの「Sprite Renderer>追加設定>レイヤーの順序」に(-100)を入力
  4. ヒエラルキーの「background>back>bg-stars」をクリック
  5. CTRLを押しながらDキーを押す
  6. インスペクターの「Transform>位置>X」に(2.72)を入力
  7. ヒエラルキーの「background>back>bg-back (1)」をクリック
  8. CTRLを押しながらDキーを押す
  9. インスペクターの「Transform>位置>X」に(5.44)を入力

中央の背景画像を表示します。

  1. プロジェクトの「Assets>Space Shooter Assets>Artwork>background>bg-stars」をヒエラルキーの「background>stars」にドラッグ&ドロップ
  2. インスペクターの「Transform>スケール」に(1, 1, 1)を入力
  3. インスペクターの「Sprite Renderer>追加設定>レイヤーの順序」に(-60)を入力
  4. ヒエラルキーの「background>stars>bg-stars」をクリック
  5. CTRLを押しながらDキーを押す
  6. インスペクターの「Transform>位置>X」に(2.72)を入力
  7. インスペクターの「Sprite Renderer>反転>Y」にチェックを入れる
  8. ヒエラルキーの「background>back>bg-stars (1)」をクリック
  9. CTRLを押しながらDキーを押す
  10. インスペクターの「Transform>位置>X」に(5.44)を入力
  11. インスペクターの「Sprite Renderer>反転>Y」のチェックを外す

手前の背景画像を表示します。

  1. プロジェクトの「Assets>Space Shooter Assets>Artwork>background>bg-planet」をヒエラルキーの「background>planet」にドラッグ&ドロップ
  2. インスペクターの「Transform>スケール」に(1, 1, 1)を入力
  3. インスペクターの「Sprite Renderer>追加設定>レイヤーの順序」に(-20)を入力
  4. ヒエラルキーの「background>back>bg-planet」をクリック
  5. CTRLを押しながらDキーを押す
  6. インスペクターの「Transform>位置>X」に(2.72)を入力
  7. インスペクターの「Sprite Renderer>反転>Y」にチェックを入れる
  8. ヒエラルキーの「background>back>bg-planet(1)」をクリック
  9. CTRLを押しながらDキーを押す
  10. インスペクターの「Transform>位置>X」に(5.44)を入力
  11. インスペクターの「Sprite Renderer>反転>Y」のチェックを外す

▷背景スクロール

背景が多重スクロールする

・解説

背景をスクロールさせるためのスクリプトを作成します。

・手順

スクリプト「Background」を作成します。

  1. プロジェクトの「Assets」を右クリックし、「作成>C# スクリプト」をクリック
  2. 「Background」と入力してENTERを押す
  3. プロジェクトの「Assets>Background」をダブルクリック
  4. Start関数の前にスクロール制御する変数を追加
    public float speed = 0.01f;             // 1フレームに動く距離
    public float scrollWidth = 5.44f;       // ループ幅

自分のスケールに合わせて「ループの幅」を計算する処理を記述します。

  1. Start関数に以下の処理を追加
        // 自分のスケールに合わせて「ループの幅」を計算
        scrollWidth *= transform.localScale.x;

ループしてスクロールし続けるように処理を記述します。

  1. Update関数の次に以下の関数を追加
    // 物理更新時に処理
    void FixedUpdate()
    {
        // スクロール
        Vector3 pos = transform.position;
        pos.x -= speed;
        // ループ幅を超えて移動した場合
        if (-scrollWidth > pos.x)
        {
            // ループ幅分戻す
            pos.x += scrollWidth;
        }
        transform.position = pos;
    }
  1. CTRLを押しながらSキーを押してスクリプト保存
  2. Unityエディタをクリックしてビルド

スクリプトを各背景ゲームオブジェクトに割り当て、速度を設定します。

  1. ヒエラルキーの「background>back」にプロジェクトの「Assets>Background」をドラッグ&ドロップ
  2. ヒエラルキーの「background>back」をクリック
  3. インスペクターの「Background (スクリプト)>速度」に(0.005)を入力
  4. ヒエラルキーの「background>stars」にプロジェクトの「Assets>Background」をドラッグ&ドロップ
  5. ヒエラルキーの「background>planet」にプロジェクトの「Assets>Background」をドラッグ&ドロップ
  6. ヒエラルキーの「background>planet」をクリック
  7. インスペクターの「Background (スクリプト)>速度」に(0.02)を入力

プロジェクトを保存して、

  1. CTRLを押しながらSキーを押してプロジェクト保存

動作を確認します。

  1. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー開始
  2. 背景画像の3つが多重スクロールすることを確認
  3. 背景画像がループしてスクロールすることを確認
  4. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー終了

●不具合修正

▷現象確認

開始後にすぐ破壊される不具合
修正後、弾が当たるまで破壊されなくなる

・解説

弾が見えない状態でも敵に命中していましたので修正します。

・手順

修正後に現象が発生しなくなる事を確認するため、一旦不具合を確認します。
自機の前方に隕石大を配置します。

  1. ヒエラルキーの「asteroid」をクリック
  2. インスペクターの「Transform>位置」に(6, 0, 0)を入力
  3. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー開始
  4. 弾が当たる前に隕石大が破壊されることを確認
  5. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー終了

▷衝突条件修正

・解説

Debug.Logで隕石に衝突したオブジェクトの位置を確認したところ、見えないZ位置にある弾が衝突していました。
特に深く考えてませんでしたが、2Dの衝突チェックなんだから無視されて当然でした。

・手順

Z位置が0以外の場合、衝突しないようにします。

  1. プロジェクトの「Assets>Hit」をダブルクリック
  2. OnTriggerEnter2Dの「タグが同じ場合は衝突させない」処理の次に以下の処理を追加
        // Z軸が0以外の場合は衝突させない
        if (collider.gameObject.transform.position.z != 0)
        {
            return;
        }
  1. CTRLを押しながらSキーを押してスクリプト保存
  2. Unityエディタをクリックしてビルド

プロジェクトを保存して、

  1. CTRLを押しながらSキーを押してプロジェクト保存

動作を確認します。

  1. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー開始
  2. 弾が隕石台に命中してから破壊されることを確認
  3. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー終了

▷エフェクトが表示されない不具合

命中エフェクトのインスペクター情報
爆発エフェクトのインスペクター情報

・解説

プレビューすると表示されない時がありました。
100%の発生ではないので確認が難しいですが…。
恐らくエフェクトとキャラクターの表示順が同じために発生しているので、はっきり表示順を指定します。

・手順

命中エフェクトの「レイヤーの順序」を大きくして手前に出します。

  1. プロジェクトの「Assets>hit1」をダブルクリック
  2. インスペクターの「Sprite Renderer>追加設定>レイヤーの順序」に(10)を入力
  3. ヒエラルキーの左上にある「<」をクリック

同じように、爆発エフェクトの「レイヤーの順序」を大きくして手前に出します。

  1. プロジェクトの「Assets>explosion1」をダブルクリック
  2. インスペクターの「Sprite Renderer>追加設定>レイヤーの順序」に(10)を入力
  3. ヒエラルキーの左上にある「<」をクリック

動作を確認します。

  1. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー開始
  2. プレビューし、エフェクトが手前に表示されることを確認
  3. Unityエディタ上部中央のPlayボタンをクリックしてプレビュー終了

●完成

隕石と背景を追加し、遊べそうな雰囲気が出てきました。

次回はいくつか敵ウェーブを作成したいと思います。
敵グループを順番に出現させ、ループさせて遊べる形にします。

コメント

タイトルとURLをコピーしました