ARKit対応アプリ『AR Submarine』制作苦労話⑥「真面目な解説2」

2018/4/23(月)

皆さん、こんにちは!

早速、続きに入っていきたいと思います。

 

ロックオン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」コンポーネントを使用しました。

Mask_Component

「Image(光るラインImage)」の親に「Mask」を設定してあげるだけです。

今回は以上です!次回で「AR Submarine」の制作話は最終回になります!次のネタを考えなきゃ。。。ぐぅzzz

続く!

 

(Cole!Cole!クリエイターU)