【Unity】2Dシューティングを作ってみる話 #11
記事をご覧いただき、誠にありがとうございます。
予想を遥かに超えて大きい画像だったので、サイズを結構縮小させないといけませんでした。
敵の画像設定が出来たので、次は敵が発射する弾を作ります。
そしたらSprite Rendererを追加して、視認出来るようにします。
では位置が決まったらSprite Rendererを非アクティブにして、EnemyBulletにタグを付けます。
投稿主の無能です。
前回は、敵が自動で生成される処理を実装しました。
今回は、敵に画像を設定して、弾を発射出来るようにしたいと思います。
敵の画像を用意する
まずは敵の画像を用意します。
敵はどのようなものを考えているかと言うと、アメーバのようなものが侵略しに来るような感じなので、アメーバで探してみます。
戦闘機やその他、皆さん個人で敵を設定して画像を探してください。
無能が用意した画像はこちらになります。
アメーバ - イラストAC
画像の設定の方法はプレイヤーの設定の時にやりましたね。
あの時の設定方法と同じになります。
このような感じになりました。
Enemyに画像を設定した
Pixels Per Unitの値を1024にして丁度良い大きさになった
敵の弾を作成する
敵の発射する弾は、このような敵であれば仮のプレイヤーの時に作成した弾で良いと思います。
勿論、敵の感じに合わせて各自弾を作ってください。
このような感じになりました。
新規に作成する場合は、Rigidbody2DとColliderを忘れずにアタッチしましょう。
弾を作成
新規で作成する場合はRigidbody2DとColliderを忘れずにアタッチする
あとはEnemyBulletをプレハブ化します。
EnemyBulletをプレハブ化
あとはHierarchyビューにあるEnemyBulletを削除します。
この時、EnemyをHierarchyビューに出して作業したと思うので、プレハブへの変更の適用を忘れないようにしてください。
変更を適用せずに削除すると、同じ手順を繰り返す羽目になります。
判断の材料としては、Overridesを押すとNo Overridesが表示されて、ボタンが出ていなければ大丈夫です。
プレハブの削除の前には変更が適用されているかを確認
やはり一度やってことのある作業は、繰り返すと早くなっていくものですね。
では敵が弾を発射できる処理を実装します。
敵が弾を発射する処理を実装する
これも何ら難しい事は無くて、プレイヤーの弾の発射の仕組みと同じものになります。
発射ポイントを子オブジェクトに持たせて、そこから弾が出るというものです。
では発射ポイントの作成からやっていきましょう。
空のオブジェクトを作成し「EnemyFirePos」という名前にしたら、Enemyの子オブジェクトにします。
「EnemyFirePos」という空のオブジェクトを作成し、Enemyの子オブジェクトにする
そして位置を調整します。
Sprite Rendererを追加して視認出来るようにして位置を調整
EnemyBulletにタグを付ける
ここまで出来たらHierarchyビューにあるEnemyは不要なので削除します
下準備が出来たのでEnemyCotrollerに処理を追加していきます。
このようになります。
EnemyCotroller.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
public class EnemyController : MonoBehaviour
{
[Header("敵の移動スピード")][SerializeField] float moveSpeed = 1f;
[Header("敵の弾の発射")]
[SerializeField] GameObject enemyBullet; // 敵の弾
[SerializeField] Transform enemyFirePos; // 発射ポイント
[SerializeField] float shotSpeed = 5f; // 弾の速度
[SerializeField] float shotDelay = 2f; // 弾の発射の閾値
Rigidbody2D enemyRB; // 敵のリジッドボディ
float shotInterval = 0; // 弾の発射管理用
void Start()
{
// 敵のリジッドボディを取得
enemyRB = GetComponent<Rigidbody2D>();
}
void Update()
{
// 弾の発射 ---
// deltaTimeを加算
shotInterval += Time.deltaTime;
// 発射間隔が閾値未満の場合
if (shotInterval < shotDelay)
{
// 処理を中断
return;
}
// 弾の発射関数を呼ぶ
EnemyShot(enemyFirePos);
// 発射間隔をリセット
shotInterval = 0;
// --- ここまで
}
void FixedUpdate()
{
// 敵を動かす
EnemyMove();
}
// 敵を動かす
void EnemyMove()
{
// 敵に左方向のベクトルを持たせる
enemyRB.velocity = new Vector2(-moveSpeed, 0);
}
// 接触判定
void OnTriggerEnter2D(Collider2D collision)
{
// プレイヤーに接触した場合
if (collision.gameObject.CompareTag("Player"))
{
// 接触した方(プレイヤー)を破棄
Destroy(collision.gameObject);
// 自身を破棄
Destroy(gameObject);
}
// プレイヤーの弾に接触した場合
else if (collision.gameObject.CompareTag("PlayerBullet"))
{
// 接触した方(プレイヤー)を破棄
Destroy(collision.gameObject);
// 自身を破棄
Destroy(gameObject);
}
// ObjectDestroyerに接触した場合
else if (collision.gameObject.CompareTag("ObjectDestroyer"))
{
// 自身を破棄
Destroy(gameObject);
}
}
// 弾の発射
void EnemyShot(Transform firePos)
{
// 弾を生成
GameObject bulletClone = Instantiate(enemyBullet, firePos.position, Quaternion.identity);
// 弾のRigidbodyに速度ベクトルをつける
bulletClone.GetComponent<Rigidbody2D>().velocity = new Vector2(-shotSpeed, 0);
}
}この辺りはプレイヤーと同じ処理なので、説明は割愛します。
少々異なる所と言えば、Enemyが弾を発射する時は自動なので、スペースキーが押された場合という条件が不要ですので、発射の閾値を超えたら即発射するように関数を呼び出しています。
ではEnemyのInspectorビューで設定します。
設定箇所は増えた項目になります。
黄枠が設定箇所
ここまでのEnemyの変更を適用し、HierarchyビューにあるEnemyを削除します。
しかしプレイヤーが敵の弾に当たっても何ともありません。
敵の弾をすり抜ける
これは、敵の弾に接触した時の処理が無いためです。
ですのでPlayerControllerスクリプトの最後に関数を追記します。
今の状態だとPlayerShotの後に関数を追加する形になると思います。
この関数を追加します。
PlayerController.cs - 追記
private void OnTriggerEnter2D(Collider2D collision)
{
// 敵の場合
if (collision.gameObject.CompareTag("Enemy"))
{
// 接触した方(敵)を破棄
Destroy(collision.gameObject);
// 自身を破棄
Destroy(gameObject);
}
// 敵の弾の場合
else if (collision.gameObject.CompareTag("EnemyBullet"))
{
// 接触した方(敵)を破棄
Destroy(collision.gameObject);
// 自身を破棄
Destroy(gameObject);
}
}まとめ
今回は
- 敵と敵の弾の画像を設定した
- 敵が弾を発射する処理を実装した
という事をやりました。
次回は、敵やプレイヤーが消えるときにただオブジェクトの破棄がされているだけなので、爆発のようなものを作りたいと思います。
では、また次回!












コメント
コメントを投稿