Unity ゲーム開発日記:敵を作る
はじめに
今回は敵を作っていきます
まずイメージを作成
プレイヤーは四角形にしたので、 敵は丸にします
ゲームウインドウではこんな感じです
敵(Enemy)を作成
Create > 2D Objects > Sprite を選択して、名前は「Enemy」とします
Sprite のイメージには先ほど作成した Enemy 用のイメージを選択
Playerと同じようにRigidbodyをアタッチします
EnemyManagerを作成
まず、空のオブジェクトを作成して名前を「EnemyManager」とします
新規のC#スクリプトを作成して、「EnemyManager」とします
void Start () { for(int i = 0; i < 10; i++) { Instantiate(enemy, new Vector3(10f, 10f, 0f), Quaternion.identity); } }
とりあえずStart関数では、Enemyを10体作成するようにしました
原点に置くとPlayerとかぶってしまうので遠くに置いています
Enemyを動かす
EnemyDriver.csというスクリプトを作成します
public class EnemyDriver : MonoBehaviour { public float enemySpeed = 1.0f; Rigidbody enemyRigidbody; // スクリーンの大きさ Vector3 min; Vector3 max; // 進行方向 Vector3 enemyDirection; void Start () { enemyRigidbody = GetComponent<Rigidbody>(); // スクリーンの大きさを取得 min = Camera.main.ScreenToWorldPoint(new Vector3(0, 0, 10f)); max = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, 10f)); // ランダムに座標を決める Vector3 enemyPosition = new Vector3(0, 0, 0); enemyPosition.x = Random.Range(min.x, max.x); enemyPosition.y = Random.Range(min.y, max.y); if(enemyPosition.x > -2f && enemyPosition.x < 2f && enemyPosition.y > -2f && enemyPosition.y < 2f) { enemyPosition.x += Random.Range(-5f, 5f); enemyPosition.y += Random.Range(-5f, 5f); } transform.position = enemyPosition; // ランダムに進行方向を定める Vector3 angle = new Vector3(0, 0, Random.Range(0, 360)); enemyDirection = Quaternion.Euler(angle) * Vector3.up; enemyRigidbody.velocity = enemyDirection * enemySpeed; } void Update () { WallCollision(); EnemyLookAt(); } void EnemyLookAt() { // 進行方向に向かせる(2Dであることに気をつける) float angle = GetAngle(enemyDirection); transform.eulerAngles = new Vector3(0, 0, angle - 90f); } float GetAngle(Vector3 v) { float rad = Mathf.Atan2(v.y, v.x); return rad * Mathf.Rad2Deg; } void WallCollision() { if (transform.position.x < min.x) { Rebound(1); } if (transform.position.x > max.x) { Rebound(2); } if (transform.position.y < min.y) { Rebound(3); } if (transform.position.y > max.y) { Rebound(4); } } // enemyが壁に当たって跳ね返る void Rebound(int flag) { // 壁に当たったら位置を戻す Vector3 pos = transform.position; if (flag == 1) pos.x = min.x; else if (flag == 2) pos.x = max.x; else if (flag == 3) pos.y = min.y; else if (flag == 4) pos.y = max.y; transform.position = pos; // XまたはY方向の速度を逆にする if(flag == 1 || flag == 2) enemyDirection.x = -enemyDirection.x; else if(flag == 3 || flag == 4) enemyDirection.y = -enemyDirection.y; // 速度を更新 enemyRigidbody.velocity = enemyDirection * enemySpeed; } }
スクリーン内をランダムに動き回るようにしました
かなり力技になってしまいましたがこれで良しとしておきます(勉強します)
参考
Enemyの進行方向を決定する処理のために参考にしました
Enemyから弾を撃つ
以前に作ったPlayerが弾を撃つ関数を改良しました
PlayerとEnemyで共通の関数を利用することにします
public class ShotBullet : MonoBehaviour { public bool isShoot = true; public GameObject shotBullet; public GameObject bullet; IEnumerator Start() { while (isShoot) { // 弾をプレイヤーと同じ姿勢でインスタンス化 GameObject sb = Instantiate(shotBullet, transform.position, transform.rotation); GameObject b = Instantiate(bullet, sb.transform); b.transform.position = sb.transform.position; b.transform.rotation = sb.transform.rotation; // 0.3待つ yield return new WaitForSeconds(0.3f); } } }
public class Bullet : MonoBehaviour { public float bulletSpeed = 4f; void Start () { GetComponent<Rigidbody>().velocity = transform.up.normalized * bulletSpeed; } // Update is called once per frame void Update () { } }
まず、空のオブジェクト「ShotBullet」をPlayerまたはEnemyの姿勢に合わせて作成
次に「Bullet」オブジェクトを作成して「ShotBullet」の"子"とします
「Bullet」は「ShotBullet」の座標系に従って真っすぐにとんでいきます
おわりに
敵を作成しました
次は当たり判定を付けていきます
これができればシューティングゲームにおける最低限のシステムを作ったことになります