健康な男子であれば誰でもレーシングゲームで順位をリアルタイムに出すにはどうやればいいのか考えたことがあると思います。
直線コースならわかりそうですが、曲線でつながっているコースはすぐには想像できないのではないでしょうか。まずはチェックポイントを通過しているかを判定するアルゴリズムを考えましょう。
前のフレームの座標をA、今のフレームの座標をB、チェックポイントをPとします。また、コースの進行方向を向いているチェックポイント平面を考えます。
いきなり答えを書くと、「PAとPCの内積」「PBとPCの内積」この2つを求めて符号が違ったら平面を通過しています。コースの進行方向に対して順方向なのか、逆方向なのかということなので、内積の定義から明らかですね。
また、逆走も簡単にわかります。車の進行方向とコースの進行方向の内積がマイナスなら逆走しています。
以上から、チェックポイントを通過した判定ができるのでその回数を数えれば順位はわかりそうですが、同じチェック区間内の順位はどう判定すればいいでしょうか?
これも内積の値でわかります。いま所属してるチェック区間の進行方向の単位ベクトルと、チェックポイントからいまの座標までのベクトル、この2つの内積の値が「進行度」になります(単に「チェックポイントからの距離」だけではダメです。進行方向に対して斜めに走っていったほうが距離が長くなってそっちが順位が上になってしまうので)。
以上より
- チェックポイント平面を通過した数が多いほうが、上位になる。
- (同じ場合は)その区間での進行度の値が大きいほうが、上位になる。
実装のサンプルです。車のアセットは無くても動きます。(技術ブログなのに開設1年以上たってはじめての実装例……)
https://github.com/mijinko-games/racing_ranking
チェックポイントのプレハブをコース上の曲がるところに配置して通し番号を付けてください。実行すると通し番号順につなげてチェックポイント区間が作られます。
横に膨らんだコース取りをしている車同士も正しく順位判定ができています。
左上の小さい逆走ボタンを押すと各自思い思いに逆走しだすので、その判定も正しくできていることが確認できます。