第09回

プレイヤーの移動制限と様々な修正

プロジェクトの準備

  1. このページは 2Dシューティングゲーム を初心者用に説明したものです。
    ダウンロードした「第08回プロジェクト」から Assets/Scene/Stage.unity のダブルクリックで起動します。
    Script にエラーがあるらしく、このままでは動かないのでエラーを修正して下さい。(前回の修正も参考にして下さい)
    .velocity が使われている行を次のように修正して下さい。
    【修正前】
    rigidbody2D.velocity =  ・・・(任意の文字列)
    
    【修正後】
    GetComponent<Rigidbody2D>().velocity = ・・・(任意の文字列)
    
  2. Background.cs の次の行を修正して下さい。
    【修正前】
        renderer.sharedMaterial.SetTextureOffset ("_MainTex", offset);
    
    【修正後】
        GetComponent<Renderer>().sharedMaterial.SetTextureOffset ("_MainTex", offset);
    
  3. Player.cs の次の行を修正して下さい。
    【修正前】
        // ショット音を鳴らす
        audio.Play();
    
    【修正後】
        // ショット音を鳴らす
        GetComponent<AudioSource>().Play();
    
  4. 修正が終わるとエラーが消えて実行可能になります。
    実行を確認してメニューの File→Save Scene で保存して下さい。

プレイヤーに移動制限つける

  1. カメラが映る範囲のことを View Port(ビューポート)と言います。
    ビューポートでは正規化された値を使用するので範囲は 0.0~1.0 の間となります。
        // 画面左下のワールド座標をビューポートから取得
        Vector2 min = Camera.main.ViewportToWorldPoint(new Vector2(0, 0));
        // 画面右上のワールド座標をビューポートから取得
        Vector2 max = Camera.main.ViewportToWorldPoint(new Vector2(1, 1));
    
  2. rigidbody2D で移動すると衝突するので、transform.position で移動するように Player.cs を修正します。
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Player : MonoBehaviour
    {
        // Spaceshipコンポーネント
        Spaceship spaceship;
    
        IEnumerator Start ()
        {
            // Spaceshipコンポーネントを取得
            spaceship = GetComponent<Spaceship> ();
    
            while (true) {
    
                // 弾をプレイヤーと同じ位置/角度で作成
                spaceship.Shot (transform);
    
                // ショット音を鳴らす
                GetComponent<AudioSource>().Play();
    
                // shotDelay秒待つ
                yield return new WaitForSeconds (spaceship.shotDelay);
            }
        }
    
        void Update ()
        {
            // 右・左
            float x = Input.GetAxisRaw ("Horizontal");
    
            // 上・下
            float y = Input.GetAxisRaw ("Vertical");
    
            // 移動する向きを求める
            Vector2 direction = new Vector2 (x, y).normalized;
    
            // 移動の制限
            Move (direction);
    
        }
    
        // 機体の移動
        void Move (Vector2 direction)
        {
            // 画面左下のワールド座標をビューポートから取得
            Vector2 min = Camera.main.ViewportToWorldPoint(new Vector2(0, 0));
    
            // 画面右上のワールド座標をビューポートから取得
            Vector2 max = Camera.main.ViewportToWorldPoint(new Vector2(1, 1));
    
            // プレイヤーの座標を取得
            Vector2 pos = transform.position;
    
            // 移動量を加える
            pos += direction  * spaceship.speed * Time.deltaTime;
    
            // プレイヤーの位置が画面内に収まるように制限をかける
            pos.x = Mathf.Clamp (pos.x, min.x, max.x);
            pos.y = Mathf.Clamp (pos.y, min.y, max.y);
    
            // 制限をかけた値をプレイヤーの位置とする
            transform.position = pos;
        }
    
        // ぶつかった瞬間に呼び出される
        void OnTriggerEnter2D (Collider2D c)
        {
            // レイヤー名を取得
            string layerName = LayerMask.LayerToName(c.gameObject.layer);
    
            // レイヤー名がBullet (Enemy)の時は弾を削除
            if( layerName == "Bullet (Enemy)")
            {
                // 弾の削除
                Destroy(c.gameObject);
            }
    
            // レイヤー名がBullet (Enemy)またはEnemyの場合は爆発
            if( layerName == "Bullet (Enemy)" || layerName == "Enemy")
            {
                // 爆発する
                spaceship.Explosion();
    
                // プレイヤーを削除
                Destroy (gameObject);
            }
        }
    }  
    
  3. Player.cs から Move()メソッドを使用しなくなったので Spaceship.cs を修正します。
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    [RequireComponent(typeof(Rigidbody2D))]
    public class Spaceship : MonoBehaviour
    {
        // 移動スピード
        public float speed;
    
        // 弾を撃つ間隔
        public float shotDelay;
    
        // 弾のPrefab
        public GameObject bullet;
    
        // 弾を撃つかどうか
        public bool canShot;
    
        // 爆発のPrefab
        public GameObject explosion;
    
        // 爆発の作成
        public void Explosion ()
        {
            Instantiate (explosion, transform.position, transform.rotation);
        }
    
        // 弾の作成
        public void Shot (Transform origin)
        {
            Instantiate (bullet, origin.position, origin.rotation);
        }
    }
    
  4. Enemy.cs に Move()メソッドを定義します。
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Enemy : MonoBehaviour
    {
        // Spaceshipコンポーネント
        Spaceship spaceship;
    
        IEnumerator Start ()
        {
    
            // Spaceshipコンポーネントを取得
            spaceship = GetComponent<Spaceship> ();
    
            // ローカル座標のY軸のマイナス方向に移動する
            Move (transform.up * -1);
    
            // canShotがfalseの場合、ここでコルーチンを終了させる
            if (spaceship.canShot == false) {
                yield break;
            }
    
            while (true) {
    
                // 子要素を全て取得する
                for (int i = 0; i < transform.childCount; i++) {
    
                    Transform shotPosition = transform.GetChild (i);
    
                    // ShotPositionの位置/角度で弾を撃つ
                    spaceship.Shot (shotPosition);
                }
    
                // shotDelay秒待つ
                yield return new WaitForSeconds (spaceship.shotDelay);
            }
        }
    
        // 機体の移動
        public void Move (Vector2 direction)
        {
            GetComponent<Rigidbody2D>().velocity = direction * spaceship.speed;
        }
    
        void OnTriggerEnter2D (Collider2D c)
        {
            // レイヤー名を取得
            string layerName = LayerMask.LayerToName (c.gameObject.layer);
    
            // レイヤー名がBullet (Player)以外の時は何も行わない
            if (layerName != "Bullet (Player)") return;
    
            // 弾の削除
            Destroy(c.gameObject);
    
            // 爆発
            spaceship.Explosion ();
    
            // エネミーの削除
            Destroy (gameObject);
        }
    }
    
  5. メニューの File→Build Settimgs から PC, Mac & Linux Standalone を選びます。
    Windows, x86 を選んで Build ボタンから Test の名前でゲームを書き出します。
    作成された Test.exe をダブルクリックで実行します。
    640*480 を選んで Windows モードをチェックします。(チェックを忘れると強制終了しなけれならない)
プロジェクトの詳細は 2Dシューティングゲーム から 「第09回 プレイヤーの移動制限と様々な修正」を参照して下さい。
第09回 の完成したプロジェクトは、後部の「今回のプロジェクトファイルをダウンロード」からダウンロードすることが出来ます。

[Next Chapter ↓] Shooting-10
[Previous Chapter ↑] Shooting-08

前田稔の超初心者のプログラム入門
超初心者のプログラム入門(Unity)