応用編1 壁の当たり判定

トップ > 3年D組モチヲ先生 > 壁の当たり判定
version 2002.8.20


□ 『壁ずり』とは?

壁ずり
現在、ほとんどの3Dゲームでは、プレイヤーが壁に突っ込むと、
図のように壁に沿って、ずりずりと移動させられるようです。
3年D組では、このような動作を壁ずりと名付けました。
さて、しごく見慣れたこの壁ずりですが、いったいどうやって実現すればいいのでしょう?
今日のこの時間は、壁ずりのアルゴリズムついて勉強したいと思います。



□ 不要な壁は取り除く

探し物
まず壁ずりをする前に、当たり判定に不要な壁を取り除くことから始めます。
ここで言う当たり判定に不要な壁とは、プレイヤーが移動した際に
絶対にプレイヤーと当たる可能性がない壁を指します。
図から見てプレイヤーpが移動した際に当たる事がない壁は、
線分AB、DE、FGになります。何故だか分かりますか?
答えは簡単です。壁の線分BC、CD、GHが手前にあり、
プレイヤーが移動してもこれらと先に当たるからです。
逆に言えば、線分BC、CD、GHは当たり判定に必要な壁と言えます。

点と直線の位置関係
その判断の方法ですが、これは点と直線の位置関係から求める事が出来ます。
左の図を見てください。先ほどを図をベクトルで表してみました。
プレイヤーpはベクトルAB、DE、FGから見ると左側の位置に存在し、
逆にベクトルBC、CD、GHから見ると右側の位置に存在します。
つまり、プレイヤーが左側に存在する時は、手前に壁がありプレイヤーと
当たる事がない壁、もしくはプレイヤーが壁の外側に居た時です。
これで、当たり判定に不要な壁を取り除く事が出来ました。
ついでに当たり判定に必要な壁も探す事が出来ました。





□ 探し物

イメージ
壁ずりをする前に、その2です。先ほど不要な壁を取り除き、
必要な壁を探す事が出来ました。ここで更に必要な壁を一つに絞り込みます。
まずプレイヤーが壁に衝突するかを調べため、壁と当たり判定を行います。
プレイヤー線分p1p2と壁の線分との2線分の交差判定を行い、
交わるかを調べます。ここで複数交差した場合は、正しい壁を選ぶため、
交点p3とp1が最も近い壁を選んでやります。(2点間の距離)
また、もしここで一つも交差する壁がなければすべての処理は終了です。
(線分同士の交差判定は、時間割に載せていないのでここでは省略します。)




□ 壁ずりをさせる

壁ずり
A,B : 壁の線分
p1 : プレイヤーの現在値
p2 : プレイヤーの未来値
p3 : プレイヤー線分p1p2と壁線分ABとの交点
p4 : p2から下ろした垂線と壁線分ABとの交点


では、壁ずりをさせるにはどうすればいいのでしょうか?
これは推測ですが、まず、プレイヤーが移動し終わった位置p2から壁に向かって垂線を下ろします。
そして出来た交点p4の位置にプレイヤーを移動してあげれば、どうやら壁に沿って移動してくれそうです。
結果、プレイヤーの壁ずりに成功しました。ゲームをプレイして貰えれば確認できると思います。
なので、プレイヤーの未来値p2を正しい方向p4の位置に導いてあげればいいので、
交点p4を求めます。求め方ですが、点と直線の距離Aから求めることが出来ます。
これで壁ずりをさせることが出来ました。



□ まだ問題は山積み

やっと、壁ずりさせることに成功しました。しかし実際のゲームでは、これだけではまだ不十分です。
ゲームのステージマップでは、凹凸な壁が存在するため、この他にも細かな処理が必要となります。

☆ 壁ずり処理のながれ
1. 移動先での当たり判定
2. 精度による誤差
3. すり抜け防止
4. フィードバックの問題
5. 簡単なトリック
以下で、これらを掻い摘んで解説します。

1.移動先での当たり判定
再度当たり判定を行う
A,B : 壁の線分
p1 : プレイヤー現在値(今は過去値)
p2 : プレイヤー未来値(今は過去値)
p3 : プレイヤーの移動元(今はプレイヤーの現在値にあたる)
p4 : プレイヤーの移動先(今はプレイヤーの未来値にあたる)

壁ずりをしたのだから、プレイヤーは壁を沿うようにp3からp4に移動したことになります。
移動したと言う事は移動先に壁があるかも知れません。
ここでp3p4を使って再度壁の当たり判定をする必要が出てきます。

2.精度による誤差
ライン上 手前に戻す
p3 : プレイヤーの現在値
n : 壁の法線ベクトル

(ちなみに、この図は超スーパー拡大図です。)

再度当たり判定を始めるのですが、ここで問題が出てくるのです。
現在値p3が壁のライン上にある事で、どうも計算した時に精度誤差から、
壁が検出できずに壁を突き抜けてしまう時があるのです。
これを防ぐため壁の法線ベクトルnの方向に、限りなく近く手前にp3を戻してあげます。

3. すり抜け防止
図8 p1 : プレイヤー現在値1
p2 : プレイヤー未来値1
p3 : プレイヤー現在値2
p4 : プレイヤー未来値2
p5 : プレイヤー現在値3
p6 : プレイヤー未来値3
ABC : 壁線分

精度による誤差も解消したので、p3p4を使って再度当たり判定を始めます。
ここで壁が検出されなければ何も問題はないのですが、もし壁が検出され
同様に壁ずりの処理をしてしまうと、図のような問題が起きてしまいます。
説明すると、まずプレイヤーp1p2が壁線分ABと壁ずりをします。
プレイヤーはp3p4となり、再度当たり判定をし壁線分BCが検出され、同様に壁ずりをします。
するとプレイヤーはp6の位置に移動してしまい、壁をすり抜けてしまうのです。
再度プレイヤーp5p6でも同じ結果を繰り返すだけなので、それを止めてあげます。
プレイヤー線分p3p4と壁線分BCの交点p5を用い、p4をp5の位置でストップさせます。
なので、壁ずりをした移動先に壁があった場合はその交点の位置で止めればいいのです。
またここでもライン上の問題が起きるので、同じように手前に戻してあげます。

4.フィードバックの問題
90度以下はダメ 90度以上はOK
90度以下の壁だと、手前に戻された時に
越えてはいけない壁まで越えてしまう。
90度以上なら、手前に戻されても大丈夫。
(ちなみに、この図は超スーパー拡大図です。)

精度による誤差で、プレイヤーを壁の少し手前に戻しましたよね。
なんとこれが原因で、90度以下のライン角度だと手前に戻されたときに、
越えてはならない壁までも一緒に通り越してしまうのです。
ではどうすればいいのでしょうか?このままでは永久に壁の当たり判定が出来ません。
どうするかと言うと、90度以下のライン角度を作らなければいいのです。

5.簡単なトリック
90度以下 90度以上
(ちなみに、この図は超スーパー拡大図です。)

90度以下のライン角度が作れないと言う事は、壁の形が限定され思い通りに作れない事になります。
90度以下の壁を作りたい場合は、次のように90度以下の壁が出来ないように工夫してやります。
この場合、描画用のデータと当たり判定用のデータは別個に用意しているので、
当たり判定のデータだけを工夫してあげます。そうすれば描画部分にはまったく問題なく
見た目にはちゃんと鋭角の壁が表現出来ます。



□ 最後に

かなり強引ではあるけれど、 これで一応『壁ずり』ができました。
「本当に!?」と思う人は、ゲームをダウンロードしてみてください。
STRONG WARRIORS 〜Over The Rainbow〜


back モチヲ先生に戻る

Copyright (C) 2001 STRONG WARRIORS. All Rights Reserved.
http://www.cam.hi-ho.ne.jp/strong_warriors/teacher/chapter09.html