コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity 入門】全方位シューティングを作る 第7回 弾の作成と発射

目次

前回のチュートリアル

はじめに

前回は、ゲームの見栄えを少し良くするために、背景がスクロールするようにしました
今回は、プレイヤーが弾を発射するようにしていきます

弾の配置

まず、弾をシーンに配置していきます

f:id:baba_s:20180331110226p:plain

「space-shooter/shots」フォルダ内の「1」を、Hierarchy の欄にドラッグします

f:id:baba_s:20180331110350p:plain

このままだと名前が分かりづらいため、
配置した「1」を選択して、名前を「Shot」に変更します

これで、弾の配置が完了しました

弾のプレハブ化

次は弾をプレハブ化していきます

プレイヤーや背景は、常にシーンに存在するオブジェクトですが、
弾は、プレイヤーが発射して始めてシーンに現れるオブジェクトです

このようなオブジェクトはプレハブ化して、
ゲーム中にたくさん複製できるようにしておきます

f:id:baba_s:20180331110615p:plain

「Scripts」フォルダを作成したときと同様の手順で、
「Prefabs」フォルダを作成します

f:id:baba_s:20180331110724p:plain

さらに、Hierarchy の欄の「Shot」オブジェクトを
「Prefabs」フォルダにドラッグします

f:id:baba_s:20180331110811p:plain

これで、弾のプレハブが作成できました

f:id:baba_s:20180331110858p:plain

シーンに存在する「Shot」オブジェクトは不要になるため、
Hierarchy で「Shot」オブジェクトを選択して、Delete キーを押して削除します

これで、弾のプレハブ化が完了しました

弾を制御するスクリプトの作成

次は、弾の移動を行うスクリプトを作成していきます

f:id:baba_s:20180331111048p:plain

「Player」スクリプトを作成した時と同様の手順で、
「Shot」スクリプトを作成します

そして、作成した「Shot」スクリプトをコードエディタで開き、
下記のコードを記述します

using UnityEngine;

// プレイヤーが発射する弾を制御するコンポーネント
public class Shot : MonoBehaviour
{
    private Vector3 m_velocity; // 速度

    // 毎フレーム呼び出される関数
    private void Update()
    {
        // 移動する
        transform.localPosition += m_velocity;
    }

    // 弾を発射する時に初期化するための関数
    public void Init( float angle, float speed )
    {
        // 弾の発射角度をベクトルに変換する
        var direction = Utils.GetDirection( angle );

        // 発射角度と速さから速度を求める
        m_velocity = direction * speed;

        // 弾が進行方向を向くようにする
        var angles = transform.localEulerAngles;
        angles.z = angle - 90;
        transform.localEulerAngles = angles;

        // 2 秒後に削除する
        Destroy( gameObject, 2 );
    }
}

さらに、「Utils」スクリプトもコードエディタで開き、
Utils クラスの末尾に下記のコードを記述します

// 指定された角度( 0 ~ 360 )をベクトルに変換して返す
public static Vector3 GetDirection( float angle )
{
    return new Vector3
    (
        Mathf.Cos( angle * Mathf.Deg2Rad ),
        Mathf.Sin( angle * Mathf.Deg2Rad ),
        0
    );
}

これで、弾の移動を行うスクリプトの用意ができたので、

f:id:baba_s:20180331111600p:plain

Unity エディタに戻り、「Shot」スクリプトを
「Shot」プレハブにドラッグして設定します

f:id:baba_s:20180331111653p:plain

「Shot」プレハブを選択して、Inspector の欄に
「Shot」スクリプトが表示されていれば、正常に反映できています

弾を発射するコードの作成

ここまでで、弾を発射するための準備ができたので、
プレイヤーが弾を発射するコードを作成していきます

「Player」スクリプトをコードエディタで開き、
m_speed 変数の下に下記のコードを記述します

public Shot m_shotPrefab; // 弾のプレハブ
public float m_shotSpeed; // 弾の移動の速さ
public float m_shotAngleRange; // 複数の弾を発射する時の角度
public float m_shotTimer; // 弾の発射タイミングを管理するタイマー
public int m_shotCount; // 弾の発射数
public float m_shotInterval; // 弾の発射間隔(秒)

次に、Update 関数の末尾に下記のコードを記述します

// 弾の発射タイミングを管理するタイマーを更新する
m_shotTimer += Time.deltaTime;

// まだ弾の発射タイミングではない場合は、ここで処理を終える
if ( m_shotTimer < m_shotInterval ) return;

// 弾の発射タイミングを管理するタイマーをリセットする
m_shotTimer = 0;

// 弾を発射する
ShootNWay( angle, m_shotAngleRange, m_shotSpeed, m_shotCount );

最後に Update 関数の下に下記のコードを記述します

// 弾を発射する関数
private void ShootNWay( 
    float angleBase, float angleRange, float speed, int count )
{
    var pos = transform.localPosition; // プレイヤーの位置
    var rot = transform.localRotation; // プレイヤーの向き

    // 弾を複数発射する場合
    if ( 1 < count )
    {
        // 発射する回数分ループする
        for ( int i = 0; i < count; ++i )
        {
            // 弾の発射角度を計算する
            var angle = angleBase + 
                angleRange * ( ( float )i / ( count - 1 ) - 0.5f );

            // 発射する弾を生成する
            var shot = Instantiate( m_shotPrefab, pos, rot );

            // 弾を発射する方向と速さを設定する
            shot.Init( angle, speed );
        }
    }
    // 弾を 1 つだけ発射する場合
    else if ( count == 1 )
    {
        // 発射する弾を生成する
        var shot = Instantiate( m_shotPrefab, pos, rot );

        // 弾を発射する方向と速さを設定する
        shot.Init( angleBase, speed );
    }
}

これで、プレイヤーが弾を発射するコードの作成が完了しました

弾の発射

最後に、プレイヤーが弾を発射するように、
Unity エディタ上で調整していきます

f:id:baba_s:20180331112410p:plain

「Player」オブジェクトを選択した状態で、
「Shot」プレハブを「Shot Prefab」の欄にドラッグして設定します

f:id:baba_s:20180331113036p:plain

そして、「Player」スクリプトの各種パラメータを設定していきます

項目 内容
Shot Speed 弾の移動の速さ 0.1
Shot Angle Range 複数の弾を発射する時の角度 20
Shot Timer 弾の発射タイミングを管理するタイマー 0
Shot Count 弾の発射数 3
Shot Interval 弾の発射間隔(秒) 0.3

f:id:baba_s:20180331113345g:plain

これで、Unity を再生すると、プレイヤーが弾を発射するようになったことが確認できます

おまけ:弾の発射数や発射速度の調整

f:id:baba_s:20180331113612p:plain

「Player」スクリプトのパラメータをこのように設定すると

f:id:baba_s:20180331113549g:plain

このように弾を発射することもできます
パラメータを変更していろいろ試してみて頂ければと思います

おまけ:弾の画像の変更

f:id:baba_s:20180331113756p:plain

「Shot」プレハブを選択した状態で
「space-shooter/shots」フォルダ内の好きな画像を
「Sprite」の欄にドラッグすることで、

f:id:baba_s:20180331113959g:plain

発射する弾の画像を変更することができます
興味があれば、いろいろな画像に変更してみて頂ければと思います

f:id:baba_s:20180331114556g:plain

f:id:baba_s:20180331114727g:plain

次回は、敵を作成していきます

次のチュートリアル

チュートリアル一覧