「【Unity 入門】全方位シューティングを作る」というサイトのチュートリアルをやってみるシリーズの5回目です。前回は自機から弾を出す作業をおこないました。
Unity全方位2Dシューティングチュートリアル4回目。弾の作成
この記事はUnityさわりたての筆者がとりあえず真似して2Dシューティングを作ってみようという感じで書いてますので解説が全く含まれていません。詳細な解説等がしりたいかたは離脱したほうがよいです。
8.敵の作成
敵の作成でやること
敵の作成でやることは大きくわけると以下の3つです。
- 敵のPrefab化
- 敵のスクリプトを作成
- 敵の出現を管理するスクリプトを作成
敵のPrefab化を行う
Prefab化を行うには一旦敵画像をhierarkhyにドラッグ&ドロップしたあとそれを用意しておいたPrefabフォルダにいれます。
敵のスクリプトを作成
敵のスクリプトを作成します。名前はEnemyScriptにしておきました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum RESPAWN_TYPE{
UP,
RIGHT,
DOWN,
LEFT,
SIZEOF,//敵の出現位置の数
}
public class EnemyScript : MonoBehaviour {
public Vector2 m_respawnPosInside;//敵の出現位置(内側)
public Vector2 m_respawnPosOutside;//敵の出現位置(外側)
public float m_speed;//速さ
public int m_hpMax;//hpの最大値
public int m_exp;//経験値
public int m_damage;//この敵がプレイヤーに与えるダメージ
private int m_hp;//HP
private Vector3 m_direction;//進行方向
//敵が生成された時に呼び出される関数
void Start () {
m_hp = m_hpMax;//HPを初期化する
}
void Update () {
transform.localPosition += m_direction * m_speed;//まっすぐ移動
}
//敵が出現するときに初期化する関数
public void Init(RESPAWN_TYPE respawnType){
var pos = Vector3.zero;//Vector3(0, 0, 0) と同じ意味
//指定された出現位置の種類で出現位置と進行方向を決定
switch(respawnType){
//出現位置が上の場合
case RESPAWN_TYPE.UP:
//public static float Range (float min, float max);//minからmaxの範囲のランダムなfloat型の数を返す
pos.x = Random.Range(-m_respawnPosInside.x, m_respawnPosInside.x);
pos.y = m_respawnPosOutside.y;
m_direction = Vector2.down;
break;
//出現位置が右の場合
case RESPAWN_TYPE.RIGHT:
pos.x = m_respawnPosOutside.x;
pos.y = Random.Range(-m_respawnPosInside.y, m_respawnPosInside.y);
m_direction = Vector2.left;
break;
//出現位置が下の場合
case RESPAWN_TYPE.DOWN:
pos.x = Random.Range(-m_respawnPosInside.x, m_respawnPosInside.x);
pos.y = m_respawnPosOutside.y;
m_direction = Vector2.up;
break;
//出現位置が左の場合
case RESPAWN_TYPE.LEFT:
pos.x = m_respawnPosOutside.x;
pos.y = Random.Range(-m_respawnPosInside.y, m_respawnPosInside.y);
m_direction = Vector2.right;
break;
}
//位置を反映する
transform.localPosition = pos;
}
}
敵の様々なパラメーターと敵出現時に初期化する関数が書かれています。switch文に列挙型が使われています。列挙型とはなにかという話になってくるのですが、とりあえずここでは触れません。ああ使われてるなあくらいでとらえておきます。スクリプトができたら敵のPrefabにアタッチします。以下アタッチした状態かつパラメーターを設定した状態です。
敵の出現を管理するスクリプトの作成
敵の出現を管理するスクリプトを作成します。名前はEnemyManagerScriptにしました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//敵の出現を制御するスクリプト
public class EnemyManagerScript : MonoBehaviour {
public EnemyScript[] m_enemyPrefabs;//敵のPrefabを管理する配列
public float m_interval;//出現間隔(秒)
private float m_timer;//出現タイミングを管理するタイマー
private void Update () {
//出現タイミングを管理するタイマーを更新する
//Time.deltaTime - 最後のフレームを完了するのに要した時間(秒)
m_timer += Time.deltaTime;
//また敵が出現するタイミングではない場合、このフレームの処理はここで終える
if(m_timer < m_interval) return;
//出現タイミングを管理するタイマーをリセットする
m_timer = 0;
//出現する敵をランダムに決定する
var enemyIndex = Random.Range(0, m_enemyPrefabs.Length);
// 出現する敵のPrefabを配列から取得する
var enemyPrefab = m_enemyPrefabs[enemyIndex];
//敵のゲームオブジェクトを生成する
var enemy = Instantiate(enemyPrefab);
//敵を画面外のどの位置に出現させるかランダムに決定
var respawnType = (RESPAWN_TYPE)Random.Range(0, (int)RESPAWN_TYPE.SIZEOF);
//敵を初期化する
enemy.Init(respawnType);
}
}
こちらは出現する敵をランダムに(この時点ではEnemy1しか作成してない)。また出現位置をランダムになるようにしているようです。RESPAWN_TYPEは列挙型でRandom.Rangeを列挙型にキャストしているのはポイントかと思います。Random.Range(0, (int)RESPAWN_TYPE.SIZEOF);はたしか列挙型は最初の要素が0からはじまるので、SIZEOFは4になりますね。
EnemyManagerScriptを作成したら「空のゲームオブジェクト」をつくってそこに同スクリプトをアタッチします。敵のPrefabをアタッチする欄があらわれるのでそこに敵のPrefabをアタッチします。パラメーターも適当に設定します。とりあえず画像を↓
ここまでの状態
たしかにランダムに出現しています。うーん地味だ。しかもこんなかんじのゲームやったことある気がする。・・・なんだかやってて意味ない気がしてきた
次の記事
ひとつひとつのコードの意味がわからないからコピペしてるだけで意味ない気がしてきた。次の記事もとりあえず作りました。当たり判定の実装です。
Unity全方位2Dシューティングチュートリアル6回目。当たり判定の実装

コメント