前回で敵を作成したのでこの敵を自動的に生成、動かすようにしましょう。
敵に動きをつける
前回作成した敵は配置したらそこに留まり続けるものでした。これを動くようにしましょう。
弾と同じように敵に対して Rigidbody をつけ、以下のように rigidbody.AddForce で力を加えてやります。
function Start () {
var velocity = transform.position;
// 速度はランダムにしとく。
velocity.z = Random.Range(-600.0, -1000.0);
velocity.x = 0;
rigidbody.AddForce(velocity);
}
これで敵が動き出します。この敵をプレハブ化しておきましょう。
敵を出現させる。
普通シューティングゲームではどこでどの敵が出るのか決まっている場合が殆どですが、一々設定するの面倒臭いので全部ランダムで出しましょう。一つ前で敵に動きをつける際にランダムにしたのもそのためです。
大体画面の上のほうに出現させるのが良いでしょう。画面に収まってる必要もありません。いきなり目の前にあらわれても困りますし。
このあたりの座標を調べると左上が -40,0,60 40,0,50 ぐらいでしたのでこの間に敵を出現させます。
まず空のゲームオブジェクトを作成します。
GameObject -> Create Empty を選択します。場所などはどこでも大丈夫です、空ですので何も見えません。これに対してスクリプトを書いていきます。EnemyGenerator にでもしておきましょう。
#pragma strict
var interval : float = 1; // 敵の発生周期
var interval_add : float = 0.1; // 敵の発生周期をどのくらい狭めるか
var interval_addtime : float = 10.0; // 敵の発生周期を狭める時間
var enemyPrefab : GameObject;
private var timer : float;
private var intervalTimer : float;
function Start () {
timer = 0.0;
intervalTimer = 0.0;
}
function Update () {
timer -= Time.deltaTime;
if (timer < 0.0) {
var offsetX: float = Random.Range(-40.0, 60.0);
var offsetZ: float = Random.Range(40, 50);
var position : Vector3 = Vector3(offsetX, 0, offsetZ);
// 敵を発生させる。
Instantiate(enemyPrefab, position, transform.rotation);
timer = interval;
}
// 時間が経つにつれ敵の出現間隔を狭めていく。
intervalTimer += Time.deltaTime;
if (intervalTimer > interval_addtime && interval > 0.1) {
intervalTimer = 0.0;
interval -= interval_add;
}
}
作成したスクリプトを先ほど作った空のゲームオブジェクトに適用しましょう。このままでは敵が上向きになっているので、空のゲームオブジェクトを180度回転させて向きが合うように調節します。その2で敵回転した意味無いですね...。
自分がこのチュートリアルを書く以前に作成したシューティングゲームでは敵がニ体いるのですが説明用に敵を一体にしたらだいぶ簡単になってしまいました...。それでも敵の速度をあげるなどすればそこそこゲームになると思います。
エフェクトの追加
敵を倒した際や自機がやられた際に何もエフェクトが出ないのは悲しいので爆発するエフェクトをつけましょう。こういったエフェクトにはパーティクルを使用すると便利です。
爆発エフェクトの作成
GameObject -> Create Other -> Particle System を選択し、パーティクルを追加します。デフォルトでは白い玉が沢山でているだけですがここに爆発の画像をつけてゲームっぽくします。
まず爆発の画像をつけてアニメーションさせます。爆発の画像は下記ページからダウンロードしました、ありがとうございます。
爆発エフェクトアニメ@EDGE(2) ? ゲーム素材製作wiki ? livedoor Wiki(ウィキ)
横5,縱3のスプライト画像になってますのでこれを使用してマテリアルを作成し、自機同様にスクリプトでアニメーションさせます。
マテリアルの作成は自機などと同じです。Project 画面 で Create -> Material を選択し、画像をドラッグして指定、Shader の値を Particles/Alpha Blended と設定し、作成したマテリアルの Tiling の x を 0.2, y を 0.33 とします。
Explode スクリプトを作成し、以下のコードを入力します。
#pragma strict
var animationFrame = 0.1;
function Start () {
var offsets = [
[0.0,0.667],
[0.2,0.667],
[0.4,0.667],
[0.6,0.667],
[0.8,0.667],
[0.0,0.333],
[0.2,0.333],
[0.4,0.333],
[0.6,0.333],
[0.8,0.333],
[0.0,0.0]
];
for (var i=0;i<offsets.length;i++) {
renderer.material.mainTextureOffset.x = offsets[i][0];
renderer.material.mainTextureOffset.y = offsets[i][1];
yield WaitForSeconds(animationFrame);
}
Destroy(gameObject);
}
function Update () {
}
爆発は一回発生させたらソレっきりなのでループせず、Start メソッド内で完結させてます。
各マスの offset の値を配列にいれておいて、それを for 文でループさせています。yield WaitForSeconds で1フレームあたりの秒数を指定しています。このあたりは好みで良いでしょう。
これを先ほどの Particle に設定して動かしてみましょう。多分、そのままでは爆発エフェクトが散らばりすぎて見た目がよくないと思います。なのでパーティクルの設定を変更します。
Particle の Inspector 画面でいろいろ設定が行えるのですが、設定項目が多くてどれをいじるとどうなるのかがわかりにくいです。ここでは簡単に発生場所、発生エフェクト数、サイズ、時間あたりをいじっていきます。
変更したのは以下の場所です。
Duration 1.00
Looping off
Start Size 10
Emission/Rate 5
Shape/Shape Box
Shape/Box X 7
Shape/Box Y 7
自機と敵が死んだらエフェクトを出す
これを自機と敵が死んだタイミングで発生するようにスクリプトを修正しましょう。
まず自機が死んだ時に行う処理はその2で作成した通り、Player スクリプトにある ApplyDamage がその役目を担ってます。ですのでそこで自機を消滅すると同時に爆発エフェクトを出すようにします。
スクリプト先頭に爆発エフェクトのプレハブを格納する変数を追加し、ApplyDamage を以下のように書き換えます。
var explodePrefab : GameObject;
(中略)
function ApplyDamage() {
Instantiate(explodePrefab, transform.position, Quaternion.AngleAxis(90,Vector3.right));
Destroy(gameObject);
}
次に敵が死んだ時です。これは OnTriggerEnter の中に書いていきましょう。
var explodePrefab : GameObject;
(中略)
function OnTriggerEnter (other : Collider) {
if (other.gameObject.tag == "Player") {
other.gameObject.SendMessage("ApplyDamage");
} else if (other.gameObject.tag == "Bullet") {
Instantiate(explodePrefab, transform.position, Quaternion.AngleAxis(90,Vector3.right));
Destroy(gameObject);
} else {
Destroy(gameObject);
}
}
爆発エフェクトのプレハブをいれるのを忘れないようにしましょう。
続く...。
コメント
[…] Unity3Dで2Dのシューティングゲームを作ってみるチュートリアルその4 – …(8)スコアと残機の実装 – tanaka’s Programming Memo […]