【Unity】2Dシューティングを作る ~プレハブで弾の発射~

Unityプレハブで弾を発射 unity

プレイするゲームがないなら、自分で作ればいいじゃない!

ということで初心者が Unity を使って「ゲームを作る」ゲームをやっていきます!

今回は「弾を発射させるまで」の記事です

 

スポンサーリンク

弾を作る

まずは画像を用意しましょう

こちらを使用

 

用意した画像を選択して、画像用フォルダーにドラッグ&ドロップします

続いて追加した画像をシーンビューにドラッグ&ドロップします

Unityで画像をオブジェクト化

 

弾をプレハブにする

プレハブにしたいオブジェクト(今回は弾)を選択し

アセットフォルダにドラッグ&ドロップします

プレハブ化に成功すると色が変化します

Unityでプレハブ化する

 

ヒエラルキービューのプレハブは消しておきます

 

スクリプトからプレハブを生成

スクリプトに「インスペクタービューからプレハブを設定できる変数」を追加します

public class PlayerController : MonoBehaviour
{
    public float fMoveSpeed = 7.0f;     // 移動値
    //---------------------------
    //          追加
    public GameObject BulletObj;        // 弾のゲームオブジェクト
    //---------------------------

 

プレハブを選択して、追加された項目にドラッグ&ドロップします

エディタでプレハブをセット

 

追加したスクリプトの Update() の中に下記を追加します

// ボタンを押したとき
if( Input.GetButtonDown("Fire1") )
{
    // 弾の生成
    Instantiate(BulletObj);
}

 

Input.GetButtonDown

ボタンを押したときに true を返します

1度ボタンを離さないと、再度 true にならない

 

Instantiate

オブジェクトをクローンします

色々設定することもできる

 

これで実行すると…

弾が生成されました!

 

しかしプレイヤーがどこにいても中央に表示されるので

プレイヤーの位置から出るようにしていきます

 

クローンの位置を設定する

プレイヤーのオブジェクトを選択⇒右クリックから「空のオブジェクトを作成」

弾の発射位置用の子オブジェクトを作成します

Unityポイント追加
ShotPointの方がしっくりくる?

 

子オブジェクトを弾の発射位置に移動させます

Unity発射位置を設定

 

弾の発射位置を保持する変数を追加
Vector3 bulletPoint;                // 弾の位置

 

発射位置を取得する
void Start()
{
    bulletPoint = transform.Find("BulletPoint").localPosition;
}

transrom.FInd(探したい子オブジェクトの名前)で transform が取得できる

transform.localPosition:親の Transform オブジェクトから見た相対的な位置
           インスペクタービューに表示されている数値

 

生成時に位置を設定する
Instantiate(BulletObj, transform.position + bulletPoint, Quaternion.identity);

ここで今の位置に弾の位置を加えた値を渡します

現状回転情報は必要ないので Quaternion.identity でOK

 

これで実行すると…

プレイヤーの位置に表示されるようになりました!

 

続いて弾を移動させます!

 

弾の移動

弾のプレハブにC#スクリプトをアタッチします

移動値に時間をかけて、足すだけの簡単なスクリプトです

public class PlayerBullet : MonoBehaviour
{
    public float MoveSpeed = 20.0f;         // 移動値

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        // 位置の更新
        transform.Translate(MoveSpeed * Time.deltaTime, 0, 0);
    }
}

 

実行すると、弾が飛んでいきました!

連射していると…

Unityオブジェクトの残骸

 

オブジェクトが消えずに溜まっているのを発見!?

次は弾オブジェクトを消す対応です

 

弾を消す

弾を消すためには

まず消える条件を考えます

・時間(フレーム)で消す
・プレイヤーとの距離で消す
・カメラの範囲外で消す

・何かに当たったら消す

 

パっと思いついたのはこれくらいでした

今回は簡単にできそうな「フレームで消す」「距離で消す」を対応します

 

オブジェクトを消す

Destroy(object, time);

Destroy でオブジェクトを消すことができます

tIme は消えるまでのディレイ時間設定で、省略することも可能

 

フレームで消す

フレームカウントと削除フレーム数のメンバ変数を追加します

int frameCount = 0;             // フレームカウント
const int deleteFrame = 180;    // 削除フレーム

 

Update() の中にフレームで消す処理を追加

// 一定フレームで消す
if (++frameCount > deleteFrame)
{
    Destroy(gameObject);
}

 

距離で消す

削除距離用の変数を追加

const float deleteDistance = 35 * 35;   // 削除距離

 

プレイヤーオブジェクト用の変数を追加

GameObject playerObj = null;     // プレイヤーオブジェクト

 

Start() の中でプレイヤーオブジェクトを取得しておく

// ヒエラルキービューにある player を取得
playerObj = GameObject.Find("player");

 

Update() の中に距離で消す処理を追加

float distance = (playerObj.transform.position-transform.position).sqrMagnitude;
            
// 一定の距離が離れたら消す
if(distance > deleteDistance)
{
    Destroy(gameObject);
}

 

Vector3.sqrMagnitude

Vector3.Distance() より処理が軽いため、こちらを使う方が良いとのこと

これにより削除距離の値は2乗になっている

 

サンプル動画

 

さいごに

これで弾を発射することが出来ました!

次回はプレイヤーの処理で少し気になっている箇所を修正したいと思っています

特に問題ないっぽかったので、次回は当たり判定の追加

かれいど

ゲームをしたり、作ったり
色々な事に挑戦していきたい!

サッカー観戦も趣味で
主にJ1リーグを観ています。

かれいどをフォローする
unity
スポンサーリンク
シェアする

コメント