読者です 読者をやめる 読者になる 読者になる

夏までにiPhone アプリつくってみっか!

趣味でiPhone/Androidアプリを開発し、日々勉強した事を書いています。オープンワールド系レースゲームをUnityで開発中です。

【Unity5でレースゲーム】道に迷わないようにミニマップを表示

Unity オープンワールドレーシングゲーム

今回はミニマップを表示してみました。

ミニマップというのはレースゲームで良くある、上から見たコース図が画面の端でカーナビ的にグルングルン回っているアレです。
市街地のオープンワールド系のレースゲームではこれがないと簡単に道を間違えてしまうので非常に重要な要素となります。

今回作った物はこうなりました。
f:id:takujidev:20150721182323j:plain

カメラを1つ作成し、Projection をOrthographicにして真下に向ければだいたい完成なのですが、それだとかなり処理が重くなりフレームレートが半分くらいになってしまいました。
なぜなら、小さいとは言えかなりの数のオブジェクトをこちらのカメラでも表示しなければならないからです。
なので、表示するオブジェクトを厳選しました。

ZenrinのJapanese Otaku Cityアセットでは道路、線路、川それぞれ1つのオブジェクトにしてくれていますので、それらにミニマップ専用のレイヤーを与えます。
それぞれのオブジェクト名は下記の通りです。
PQ_Road
005339_08932_train
005339_08932_water
これらにMinimapなど適当なレイヤーを割り当てます。
ミニマップ用カメラのCulling Maskにこのレイヤーを割り当てると完成です。
普通に表示するとミニマップの部分がゲーム画面を隠してしまって邪魔に感じられますが、このように道路、線路、川だけだと網目から向こうが見えるので、邪魔な感じがやわらぐのも良いと思います。

カメラを自車の子オブジェクトにすれば比較的簡単に自車を追って、回転も自動的にしてくれますが、自車がクラッシュして宙をぐるぐる舞うとミニマップまでぐるぐるおかしくなってしまうので、スクリプトで自車を追うようにしています。

using UnityEngine;
using System.Collections;

public class MinimapCamera : MonoBehaviour {

    public Transform target;

    private const float _height = 100f;

	void Start () {
        StartCoroutine(UpdatePosition());
	}

    IEnumerator UpdatePosition () {
        while (true) {
            yield return new WaitForFixedUpdate();
            transform.position = new Vector3(target.position.x, _height, target.position.z);
            transform.eulerAngles = new Vector3(90f, 0f, -target.eulerAngles.y);
        }
    }
}

以前作ったコルーチンでWaitForFixedUpdate()を使う方式なので、1フレーム遅れる事なく自車に追従してくれるはずです。

参考:tf.hateblo.jp

transform.eulerAnglesでzのところにターゲットのeulerAngles.yを入れているのは、カメラがx軸で90度下に向いているためです。
カメラをコマのように地面に垂直に回すためには、カメラのz軸が通常のオブジェクトのy軸に相当します。値をマイナスにしているのは常に自車の向きを画面の上向きにしておくためです。
自車が左を向いたときにカメラを同じだけ右に回せば結果的に自車の向きは変わらず、地面が回ります。

あとは、自車や他車、コーナーの位置をミニマップ上に表示するためのアイコンを作ります。

写真では四角いドットで表現されていますが、実際に巨大な四角(Quadオブジェクト)を自車や他車にくっつけています。(これが正しいやり方なのかどうか自信はないです。)
シーンビューで上空から見るとこんな感じです。
f:id:takujidev:20150721185542j:plain
コライダーコンポーネントは外し、レンダラーの影の設定などは全てOFFにしていますのでゲームに影響は与えません。
また、これらには専用のレイヤーを与え、ミニマップ用カメラのCulling Maskに追加しています。
逆に、メインカメラのCulling Maskでは除外していますので、メインカメラには一切映りません。
Quad同士の重ね合わせはQuadの高度を変える事で優先順位を付けられます。コーナー用の水色が一番上、その下が自車用の緑、一番下が他車用の赤になっています。
また、これらの四角はミニマップ用カメラと同じようなスクリプトで動かして、たとえ車が転げ回っても常に真上を向くようにしています。

今回の動画です。

ミニマップとは関係ありませんが、前回改良してまともになった木の影の形がわかると思います。ただ、シェーダーを変えたためか木の緑色が若干おかしくなった気がしますが、今は気にしないことにします。