レーシングゲームにおける逆走判定
ほとんどのレーシングゲームでは、逆走した時に逆走したことを示すメッセージが表示される。
逆走したことのメッセージが存在しないと、
プレイヤーが逆走に気がつかないまま逆走を続けてしまう可能性があり、非常に不親切である。
現在作成しているアプリでも同じ機能をつける必要があり、
逆走判定を行う必要が出てきたため、逆走判定のアルゴリズムをまとめてみた。
候補となるアルゴリズムは、以下の3つである。
1. 進行方向を示すマップを作成し、現在地の進行方向と自身の進行方向を比較
[アルゴリズム]
2Dまたは、3Dで高さ成分をあまり考慮する必要がない場合は、
2次元配列等を利用して、各場所における進行方向を持つマップを作成すればよい。
3Dで高さが大きく変更される場合(フライトレーシング等)は、
3次元配列を用いて3D空間上を表現すればよい。
[利点]
それぞれの場所で進むべき進行方向の判定が行えるため、
逆走した瞬間に検知可能である。
[欠点]
判定の精度を細かくしたい場合、進行方向を指定する場所が増え、
進行方向の入力の手間が非常にかかってしまう。
特に3D空間の場合、すべての部分に進行方向を入力するのは非現実的である。
2. チェックポイントを設置し、チェックポイントの通過方向から判定
[アルゴリズム]
コースを複数のセグメント(区分)に分割して、
セグメントが切り替わる部分にチェックポイント(判定ポイント)を置いておく。
それぞれのチェックポイントは、通過点であることを考えると、
2Dでは進行方向と垂直な直線、3Dでは進行方向と直角に交差する板ポリが良い。
設定したチェックポイントを通過した時、チェックポイントの通過方向から、
逆走の判定が可能である。
手前から奥の場合は順方向、奥から手前の場合は逆方向と判断すればよい。
[利点]
3Dへの対応が簡単である。
また、複雑な地形に対しても、板ポリや直線を向きに気をつけながら設置するだけで良いので、
1.に比べて、かかる手間が少ない。
判定の精度を細かくしたい場合にも上記の利点が当てはまる。
[欠点]
チェックポイントの通過が判定のタイミングとなるため、
チェックポイントを通過しない限り、判定することができない。
チェックポイント間の距離が長いと、プレイヤーはなかなか逆走に気がつけない。
3. チェックポイントを設置し、次に進むべきチェックポイントと、進行方向を比較して判定
[アルゴリズム]
2.と同様に複数のセグメントに分割し、セグメントが切り替わる部分にチェックポイントを置くか、
ルートに沿ってWayPointを置く。
どちらの場合にも、粒度が小さい場合には正しい判定が行えないため、設置方法には気をつける必要がある。
特に直線なら粒度が低くても問題ないが、カーブが急な所では粒度を高くしなくてはならない。
逆走判定は、次に進むべきチェックポイントと、一番最後に通過した(接近した)チェックポイントから進行方向を割り出し、
プレイヤーの進行方向との内積を取ることによって行う。
例えば、以下の条件を満たす場合に逆走したと判断する。
( c1 - c0 ) ・p < r * | c1 - c0 | * | p |
c0: 一番最後に通過したチェックポイントの位置
c1: 次のチェックポイントの位置
p: プレイヤーの進行方向
r: 逆走とみなす範囲(1.0から-1.0の間)
rは1.0から-1.0の値を取り、値が大きいほど逆走判定が大きくなる。
1.0では、いかなる方向でも逆走と判定し、-1.0では逆走と判定されない。
そのため、基本的には0.0(後ろ半分を逆走と判定)以下にする。
[利点]
2.と同様、3Dへの対応が簡単である。
常に逆走判定が行える。
[欠点]
チェックポイントの置き方が良くないと、誤判定する可能性がある。
このため、チェックポイントの置き方を十分考慮する必要があり、手間がかかる。
理想的には3.が良いのだが、2.では生じなかった誤判定が起こりやすかったため、
現在作成しているアプリでは2.を採用することにした。
加えて3.は、チェックポイントを慎重に設置する必要であるため、
Unity上ではなかなか面倒だと感じた。