アマゾンバナーリンク

ディスプレイ広告

スポンサーリンク

Unityオンラインゲーム制作でバスに乗り降りするための技術

こんにちは!ジェイです。昨日のYouTubeで、バスに乗るためにリスナーさんと引き続きテスト配信をしました。結果はバスが吹っ飛ばなくはなったが、降りれなくなる現象に悩まされました。

記事内広告

現状の問題点

以前はバスが吹っ飛んでいたので、その対策にRigidbodyのisKinematicをtureにして、重力の干渉を切ることによって、飛ばなくしてました。しかし、このisKinematicが原因で飲酒運転でフラフラ運転状態になってしまいました。

ということでiskinematicをtrueにすると飲酒運転になり、falseにするとバスが吹っ飛ぶという究極の選択になりました💦

更なる問題点

上記の問題も大変な問題ですが、一度乗ると降りれなくなるという現象にも悩まされました。

しかし、昨日の配信でこの問題点の原因は、その席に乗っているかどうかのフラグが同期されてなくて、同じ席の番号のオブジェクトの子が2人以上になってしまうというものでした。以下の動画でsitpointに1人ずつ子オブジェクトとして、キャラクターが設定されるはずが、1つのsitpointに2人入ってしまう現象の事です。

リスナーさんが出してくれた解決案

この乗り降りを難しくしている原因は、入口が1つだけなのに対して、座る座席が複数あるため、それに対応する番号を同期させるのが大変なのです。

これに対して提示してくれた解決策は、1つの出入り口に対して、1つの席だけにするというものです。これなら空いている席をわざわざ検索して探さなくても、出入りすることができます。実際に他の車ではその様な仕様にしているので、この方法は確実にできる保証があります。

Rigidbodyに関しても、PhotonTransformViewを使いTransformのみの操作でもバスを動かす事はできるので、最後はその方法でやろうと昨日の時点では思っていました。

急に思いついた新たな解決策

しかし、今日の朝ずっと考えていて、思いついたのが、そもそもフラグを同期させるのではなく、sitpointの子オブジェクトにPlayerが1人もいなければ、そこに乗れるようにすればいけるんではないかと思い試してみました。

以前のフラグ検索のコード

昇順に線形探索して、一番最初にIsOccupiedがtrueを返した値を席番号として使っていました。

public int GetAvaliableSeat(int start=0)
{
    for (int i = start; i < _BattlePhazeEnterExit.EnterExitSeats.Count; ++i)
    {
        if (!_BattlePhazeEnterExit.EnterExitSeats[i].IsOccupied)
        {
            return i;
        }
    }
    return -1;
}

改良後のコード

「sitpointの子オブジェクトが無ければ、その値を返して、もしあったなら線形探索をして、Playerでなければその値を返す」GetVacantSeat関数をsitpointの数だけ繰り返すGetAvaliableSeatを使い全部の席から空いてる場所を探します。

public int GetVacantSeat(int seat_index)
{
    if (EnterExitSeats[seat_index].PlayerSeatTransform.childCount == 0)
    {
        return seat_index;
    }
    else
    {
        for (int j = 0; j < EnterExitSeats[seat_index].PlayerSeatTransform.childCount; ++j)
        {
            Transform seat_child = EnterExitSeats[seat_index].PlayerSeatTransform.GetChild(j);
            if (!seat_child.CompareTag("Player"))
            {
                return seat_index;
            }
        }
    }
    return -1;
}
public int GetAvaliableSeat(int start = 0)
{
    int num = -1;
    for (int i = start; i < EnterExitSeats.Count; ++i)
    {
        num = GetVacantSeat(i);
        if (num != -1)
        {
            return num;
        }
    }
    return -1;
}

実行結果

今の時点では1人でテストしただけなので、明日またテスト配信をしてもしこれがいけたなら、長かった乗り物の実装も終わります!!

もし結果が気になる方はぜひYouTubeチャンネルの登録をしてぜひお見逃しないようお願いします。

チャンネル登録はこちらから