ARKit対応アプリ『AR Submarine』制作苦労話⑥「真面目な解説2」
皆さん、こんにちは!
早速、続きに入っていきたいと思います。
ロックオンUIを作成。サメを捉えると色が赤くなるように。また、ミサイルを発射した後、3秒間のインターバルを置いて、何発も連続して撃てないようにしました。
サメのロックオンには、「Ray」を使用しています。Rayの使い方はこんな感じです。
public LayerMask mask; //Inspectorからプルダウンでレイヤーを選択可能
void Update () {
// Rayの作成(Rayの発生地点、Rayの進む方向)
Ray ray = new Ray(this.transform.position, transform.forward);
RaycastHit hit; //衝突したオブジェクトの情報を得る為に使用
//衝突判定(判定するRay、Rayの太さ、衝突したオブジェクトの情報を得る、
//Rayの長さ、衝突するレイヤー)
if (Physics.SphereCast(ray, 0.2f, out hit, 8f, mask)) {
//オブジェクトにRayが当たった場合、そのオブジェクト名をログに表示する
Debug.Log(hit.collider.gameObject.name);
}
}
上記コードを利用して、サメにRayが当たったら、ロックオンUIのState Machineを遷移させてアニメーションをしています。
ゲーム内の主な説明はだいたいこんなところです。ボタンやBGM・SEの配置については省略します。まだ何か忘れてそうですけども・・・。
続いてスタート画面。別でシーンを作って、見栄え良くしていきます。
サメと小魚たちが仲良く泳いでいます(笑)。このサメと小魚のスポーンする位置は、指定範囲内の中で毎回ランダムに変わります。
「Random.Range(min, max)」
//例
transform.position = new Vector3(Random.Range(-25.0f, 25.0f), Random.Range(-1.0f, 15.0f), Random.Range(-12.5f, 32.5f));
「Random.Range()」を使う注意点として、int型を使う場合、二つ目の最大値maxは含まれません。例えば「Random.Range(0, 10)」にした場合、0~9のいずれかの値が返される事になります。今回はfloat型を使用しています。
あと、あんまり自由に泳ぎ回って、明後日の方向に行っても困るので、「Bounds」を利用して移動範囲を制限しています。これはゲームシーンでも同様です。「Bounds」は3次元空間の範囲を表します。
泳がせたい範囲の「Cube」を作って、その「Cube」の大きさを「Bounds」で取得。「min」「max」で最小値・最大値を得られるので、上記の「Random.Range()」を使用して「Cube」内のランダムな位置を取得できます。その値を小魚やサメの進む目標地点とすればOKです。水槽の中を泳いでいるイメージですかね。
//例
public Bounds bounds; //Bounds
public GameObject cube; //泳がせたい範囲の「Cube」
private float lerpT = 3.0f;
private float speed = 5.0f;
private Vector3 targetPosition; //目標地点
private float changeTargetSqrDistance = 1.5f;
void Start () {
bounds = cube.GetComponent().bounds;
}
void Update() {
// 目標地点との距離が小さければ、次のランダムな目標地点を設定する
float sqrDistanceToTarget = Vector3.SqrMagnitude(transform.position - targetPosition);
if (sqrDistanceToTarget < changeTargetSqrDistance) {
targetPosition = Random_position();
}
// 目標地点の方向を向く
Quaternion targetRotation = Quaternion.LookRotation(targetPosition - transform.position);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * lerpT);
// 前方に進む
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
//「Cube」内のランダムな位置を返す
public Vector3 Random_position() {
return new Vector3(Random.Range(bounds.min.x, bounds.max.x), Random.Range(bounds.min.y, bounds.max.y), Random.Range(bounds.min.z, bounds.max.z));
}
タイトルロゴやボタンの作成には3ds Maxを使用しています。光るラインが走る表現は、「Mask」コンポーネントを使用しました。
「Image(光るラインImage)」の親に「Mask」を設定してあげるだけです。
今回は以上です!次回で「AR Submarine」の制作話は最終回になります!次のネタを考えなきゃ。。。ぐぅzzz
(Cole!Cole!クリエイターU)