その1ではプレーヤーキャラクターの作成までやりました。あとは敵を作りましょう。
敵を作る
これも地面と同じように立方体とマテリアルの設定で適当に作ります。
はい、クリーパーさんですね。今回はとりあえず作るだけなので爆発はしないです。
見た目を作ったらこのクリーパーさんに rigidbody を適応します。これを選択した状態で Component -> Physics -> Rigidbody を選択でOKです。Inspector の Rigidbody にある Constraints の Freeze Position の Y にチェックをいれておきましょう。そうしないとあとで動かすのが面倒です。
rigidbody の設定が終わったら tag の設定をします。これは後でプログラム上でゲームオブジェクトを識別するのに必要になります。
tag を設定するにはクリーパーを選んだ状態で Inspector の Tag にある Add Tag... を選択し、Element 0 などとなってるところの右側に追加したいタグの名前をいれます。ここでは Target としておきましょう。
攻撃したら敵が死ぬようにする
さきほど弾が出るようにスクリプト書いたので、その弾を受けてクリーパーが死ぬようにします。
以下のようなスクリプトを書いてクリーパーに適用します。
#pragma strict
function Update () {
// shot スクリプト内の targetGameObject がこの gameObject だったら消す
if (this.gameObject == shot.targetGameObject) {
Destroy(gameObject);
} else {
}
}
Destroy してるだけの簡単なスクリプトですね。
ちゃんと弾を撃ったら消える事を確認したらこれを Project 欄にドラッグしてプレハブ化しておきます。
敵が自動で出現するようにする
プレハブかしたクリーパーさんを自動で出すスクリプトを書きます。書きますといっても前回2Dのシューティングゲームを作成したときに書いたものをちょっと改良しただけです。
#pragma strict
var interval : float;
var interval_add : float;
var interval_addtime : float;
var target1Prefab : GameObject;
var targetVelocity : float;
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) {
// フィールド上にランダムで生成するのでそのpositionを出す
var offsetX: float = Random.Range(-25.0, 25.0);
var offsetY: float = Random.Range(1.0, 3.0);
var offsetZ: float = Random.Range(-25.0, 25.0);
var position : Vector3 = Vector3(offsetX, offsetY, offsetZ);
var prefab : GameObject = target1Prefab;
// ターゲット生成
var target = Instantiate(prefab, position, transform.rotation);
// プレーヤーに向かっていくようにする
var direction : Vector3;
var player : GameObject = GameObject.FindWithTag("Player");
if (player != null) {
direction = (player.transform.position - target.transform.position).normalized;
target.rigidbody.AddForce(direction * targetVelocity, ForceMode.VelocityChange);
}
timer = interval;
}
intervalTimer += Time.deltaTime;
if (intervalTimer > interval_addtime) {
intervalTimer = 0.0;
interval -= interval_add;
}
}
スクリプトを書いたら空のゲームオブジェクトを作成し、スクリプトを適応し、Inspector で Interval などの値を指定します。
これを実行するとクリーパーさんが続々と出てきます。爆発しないのであんまり怖くないですね?
画面外に飛んでいったクリーパーを削除する
これも前回作成した2Dシューティングゲームと同じように作ります。
フィールドを囲むように Cube で壁を作成し、Box Collider の Is Trigger にチェックをいれます。
ただ、これだけではプレーヤーの画面に壁が見えてしまってちょっと不恰好なので見えない壁にします。
見えない壁にするには、このオブジェクトの Mesh Renderer のチェックを外すだけです。こうするとゲーム画面には描画されなくなります。
そうしたら先ほど作成したターゲットのスクリプトに壁にぶつかったら削除するように以下のメソッドを追加します。
function OnTriggerEnter (other : Collider) {
Destroy(gameObject);
}
ダメージを受ける
FPS では攻撃を受けたら画面が赤くなりますね、同じように敵にぶつかったら画面をちょっと赤くしましょう。
照準を作成した時と同じように GUI Texture を作成し、適当な画像を使用して画面の中央に大きく配置します。
とりあえず適当にあった画像をつけたらなんか曇ったような感じになりましたがまーいいでしょう。
GUITexture を作成したらダメージを受けた時にこれを表示するスクリプトを書きます。
#pragma strict
function Start () {
// 色をダメージっぽく赤くする
guiTexture.color = Color.red;
// ゲーム実行時には無効化しておく。
guiTexture.enabled = false;
}
// ダメージを受けた時に実行するメソッド
function damageEffect() {
// テクスチャーが見えるようにする。
guiTexture.enabled = true;
// 0.2秒後に見えなくする
yield WaitForSeconds(0.2);
guiTexture.enabled = false;
}
スクリプトを書いたら先ほど作成したダメージの GUI Texture に適応します。
ターゲットとプレーヤーの設定
ターゲットにぶつかったら赤く表示するので、それらのスクリプトもちょっと書き足す必要があります。
まずプレーヤーから。衝突が発生したときに先ほど作成した GUI Texture の damageEffect メソッドを呼び出します。
var damage: GameObject;
function OnCollisionEnter(collisionInfo : Collision) {
// ぶつかったのがターゲットならエフェクトを出す。
if (collisionInfo.gameObject.tag == "Target") {
damage.SendMessage('damageEffect', '');
}
}
スクリプトを書いてプレーヤーに適応したら damage のところに 先ほど作成した ダメージの GUI Texture をドラッグしておきます。
次にターゲットにも OnCollisionEnter メソッドを追加しておきます。
// 空でもいいからないとプレーヤーにある OnCollisionEnter が呼ばれないっぽい
function OnCollisionEnter(collisionInfo : Collision) {
}
これでダメージを受けたら画面が赤くなるはずです。
これでひとまず FPS の完成です。Unity だと楽ですね。