Unity 5 日記 6 ショットを発射
もう適当にさっさと書かないと飽きるので雑に書いていく. さっさとショット発射してみたい. 敵にあたるとかそんなんどうでもいい.
Unity 5 日記 2 スクリプトの作成 と Unity 5 日記 3 deltaTime の適用 で作成したオブジェクトにショットの発射機能を持たせる.
作成してあった移動処理をメソッド Move
に分離し,
メソッド Update
を以下のように書き換える.
private void Update() { Move(); }
変数 float shootFreeze
と System.Collections.Generic.List<GameObject> shots
を追加する.
private QuantizedTime shootFreeze; private System.Collections.Generic.List<GameObject> shots;
ついでにメソッド Start
に各々の初期化処理を追加しておく.
void Start() { ... shootFreeze = 0; shots = new System.Collections.Generic.List<GameObject>(); }
はっきり言ってこの書き方は良くない. クソコードである. 関心の分離もへったくれもない. 本当なら別途ショットを管理するためのクラスを用意すべきだが, ここではとりあえず後回しにする.
Unity 5 日記 5 Prefab で書いたような感じで Prefab を作成し, Resouces フォルダに Shot という名前で適当にいれる.
そしてショットにスクリプトを追加する.
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ShotBehaviorScript : MonoBehaviour { // Use this for initialization void Start() { } // Update is called once per frame void Update() { var x = transform.position.x; var y = transform.position.y; var z = transform.position.z; z += Time.deltaTime * 100; transform.position = new Vector3(x, y, z); } public bool IsOut() { return 32 < transform.position.z; } }
メソッド Update
で移動を行う. IsOut
は消去判定を行うためのメソッドだ.
Unity では画面外に出たことを判定するための関数があるが,
ショットは画面外に出た時に消えてしまうのは困るので自分で色々判定する.
ここでは本当に適当な値の比較にした.
そして自機側のスクリプトにメソッド Shoot を追加する. この名前もかなり悪い.
private void Shoot() { if (0 < shootFreeze.Value) { var deltaTime = Time.deltaTime; shootFreeze -= deltaTime.Value; return; } var fire = UnityEngine.Input.GetButton("Fire1"); if (fire) { GameObject shotPrefab = (GameObject)Resources.Load("Shot"); var shot = Instantiate(shotPrefab, new Vector3(0,(float)_position.Y, (float)_position.X), Quaternion.identity); shots.Add(shot); shootFreeze.Value = 128; } }
手元のスクリプトとブログに書いてあるスクリプトが一致していないので座標周りがおかしかったり変数名があっていなかったりするが心の目で読んで欲しい. Resouces ディレクトリに入れた Prefab は上記のような感じでインスタンス化することが出来る. 生成したショットは shots に追加する.
最後に画面外に出たショットを削除するためのメソッド RemoveShots を追加する.
void RemoveShots() { for (int i = 0; i < shots.Count;) { var shot = shots[i]; var script = shot.GetComponent<ShotBehaviorScript>(); if (script.IsOut()) { Destroy(shot); shots.Remove(shot); continue; } ++i; } }
GetComponent
でアタッチしたコンポーネントを取得し,
メソッド IsOut
で判定を行い,
Destroy
関数で GameObject
を削除する.
ShotBehaviorScript
の中で Destroy(this)
するとオブジェクト全体ではなくコンポーネント単体を削除してしまうらしい.
なんかもう記事書くのも面倒になってきた. この雑さ極まるコードを GitHub に丸上げして, コミットログにリンク張って日記にする程度でいいんじゃなかろうか.