Unity レースゲームの作り方8 衝突処理の調整と順位計測ランキングシステムの実装

Unity C# レースゲームの作り方 (PC・スマホ・VRクロスプラットフォーム開発チュートリアル)


Unity入門の森オリジナル本格ゲーム制作講座はこちら
7種類の本格ゲームの全ソースコード公開・画像&動画による解説付き

と本講座ではUnityで3Dレースゲームの作り方について説明しています。

今回は第8回目となります。前回はUnityのChinemachineを利用して対戦相手となるCPUの車を作成し、自動運転の機能を実装しました。

前回の記事 :

Unityレースゲームの作り方7 Chinemachineの使い方 NPCの対戦相手を作成
本講座ではUnityで3Dレースゲームの作り方について説明しており、今回は第7回目となります。 前回の記事 : 前回記事ではマップの作成とリトライ処理を作成しました。 今回は一人でレースするのではなく対戦相手となるNPCを作成して...

それぞれの車にはコライダーを追加しているため、今のままだと衝突した際にCPUの車がおかしな挙動を取ってしまいます(車体をぶつけた後コースアウトしていったまま戻ってこないなど)。

そこで、車のコライダーや重心の調整や速度制限などをまず行います。

また、周回数を計測しているのでプレイヤーと敵合わせてレースゲーム終了後の順位を決められるようにしていきます。

では始めていきましょう!


【Line登録者限定のプレゼントもあるよ!】

CPUの調整 速度制限・体当たりされた時に元のコースに戻す処理

ここではCPUが自動で運転しながらレースを行う際に妨げとなるバグや不都合な部分を取り除いていきます。

まずは速度が出すぎた時に判定処理が成功しないと困るため、速度制限の実装からいきましょう。

対戦相手の車の移動速度の制限を実装しよう

前回少し触れました、周回数の計測にコライダーを使用しているため速度が速い時にうまく計測されない可能性があります。(Playerが追いつけないほど速度が速いとこうした計測バグが起こり得ます)

これを防ぐためにはコライダーの大きさを大きくしたり、周回数の計測方法を変更したりでもいいのですが、今回は簡単に速度を制限します。

前回作成しました、「CPU」の移動処理は、「CPUContorller.cs」の「lapTime」で1周にかかる時間を設定しており、その時間が短いほど早くなります。なのでこの値を制限すればOKです。

では、「CPUContorller.cs」を開いて修正します。

これだけです。

変更したのは、変数の「lapTime」の属性部分です。元々あった「SerializeField」の横に「,」をつけて「Range」という属性をつけます。

Range( 下限, 上限 ) : 変数に制限をつける属性。

数値は各々変更しても構いませんが、上記のように記載すると「lapTime」を「40f〜200f」に制限することができます。また「SerializeField」属性でUnityのInspectorで値が変更できますが、その際の値が制限されバーのような形になります。

 

車体同士が衝突した時にコースアウトさせないようにする処理を実装

前回周回数を計測するためにコライダーとリジッドボディを付与しました。これによりPlayerとの衝突が可能になっています。

このコライダーとリジッドボディでの衝突は、「付与されているオブジェクト」が衝突し物理的な反発などの作用がおきます。

当然と言えば当然ですが、今回コンポーネントを付与しているのは「Free_Racing_Car_Red」ですのでこのゲームオブジェクトが衝突によって動いたりします。まずはこのことを頭に置いておいてください。

次に、今回CPUの移動に使用している「Chinemachine」の機能ですが、パスの設定をし「Dolly Cart1」を動かしているというのは前回お話ししました。この「Dolly Cart1」が移動しているので、ちょうどカートのように、親に乗っかってその子にある「Free_Racing_Car_Red」も移動します。

そして、ここに衝突した場合にその影響で動くのはコライダー、リジッドボディを付与している車なので子の部分のみ動くことになります。

例えば、上方に移動しているときに左方向から衝突された場合、下記のように「Dolly Cart1」から「Free_Racing_Car_Red」のみが移動し親子間で位置の差が出ます。

しかし「Dolly Cart1」の移動が続いていれば、ずれたままで移動し続けることになります。

 

実際はここまで極端には移動しませんが、これを修正するためには親子間の位置の差がでたらその差を戻すようにしてあげればOKです。

なので処理としては、「Free_Racing_Car_Red」の位置を親である「Dolly Cart1」に合わせる続けるようにしていきます。

そして「Free_Racing_Car_Red」は「Dolly Cart1」の子なので、「Free_Racing_Car_Red」の「LocalPosition」「LoacalRotation」を全て「0」にすることが、合わせることになります。

Local Position(Rotation) : 親GameObjectからの相対距離(角度)。全て「0」というこは親と同じ位置(角度)。

では、処理を書いていきます、「CPUContoller.cs」を開きましょう。

 

まず変数に「SerializeField」で「carTransform」というTransform型の変数を作成します。これは後でInspectorで「Free_Racing_Car_Red」をドラック&ドロップしましょう。

そして、関数「FixedCarPosition()」を追加し「Update()」内で「carTransform」つまり車の位置が「0(Vector3.zero)」もしくは角度が「0(Quaternion.identity)」の時、実行します。

中の処理は、「carTransform」のローカル位置と角度を0にする処理ですが、ずっと0を入れ続けると動かない状態になってしまいますので、位置では「Vector3.Lerp」、角度は「Quaternion.Lerp」を使い徐々に位置を調整しています。

引数にある「Time.deltaTime * 1f」の「1f」ですが、係数を入れるときはこれを変更しましょう。このままでも大丈夫ですが、戻る速度が変わります。

この「Lerp」はカメラがプレイヤーを追跡する処理の時にも使用しましたが、ざっくり書き方を覚えておけばOKです。

Vector3(Quaternion) Lerp( a, b, t ) : aからbに徐々に移動する値を取得(tは補間値、移動速度に近いと思っておきましょう).
では、Unityに戻ってInspectorで「Free_Racing_Car_Red」をドラック&ドロップしたら、再生してみましょう。
適当に衝突してみてズレたのが徐々に戻るようになりました。
わかりにくい場合は、「Free_Racing_Car_Red」の「RigidBody」の「Mass」を下げると、車が軽くなるのでより大きく動きますので試してみましょう。
 

Rigidbody回転の固定

衝突できることにより、車同士などの衝突で車が変な方向に傾いてしまったりします。なので今回は簡単にCPUの車はY軸方向(左右回転)以外はできないようにしましょう。

Hierarchyの「CPU」の子の車「Free_Racing_Car_Red」を選択しInspectorで「Rigidbody」コンポーネントの「Constraints」の「FreezeRotation」でXとZにチェックを入れてください。

 

Playerの調整

Playerも少し調整します。
現在、プレイヤーの車がちょっとした段差に乗り上げた時に簡単にひっくり返ってしまうので、Rigidbodyの重心を下げることでひっくり返りにくくしていきます。
 
では「PlayerController.cs」を開いてください。

とても簡単で、「Start」関数内で、「rigid.centerOfMass」の値を「new Vector3( 0, -0.2f, 0 )」に設定します。

「centerOfMass」というのは文字通りリジッドボディの質量の中心、つまり重心です。これを「Vector3」でYの値を「ー0.2」つまり、中心より少し下に置いて転倒を防止します。

順位を決める

ここからはレースらしく順位を決めていきます。

今はPlayerとCPUの2台しかいないので、寂しい方はCPUを同じように追加してみましょう。コピーして「DollyTrack1」のルートをすこし変えるだけです。

車の色を変えたい場合は「Free_Racing_Car_Red」を別のものに差し替えますが、この時「Rigidbody」と「Collider」のコピーと、「CPUContoller.cs」のInspectorへの車のドラック&ドロップ、また「GameController.cs」の「cpuList」へのドラック&ドロップ、変更した車のGameObjectのTagを「CPU」に変更する、この4つを忘れないようにしましょう。

ここでは、ひとつ増やして「CPU2」という車を増やしました。

UIの微調整

一旦UIを調整します。現在ゴールした時のリトライUIが「Goal」の文字より前に来て邪魔になっているのでこれを調整します。そしてここに順位を表示します。

まず、Inspectorで「Canvas」の子を見てください。ここに「CountdownText」というのがあると思いますが、これをドラック&ドロップして「Retry」の下に移動して順番を変えましょう。

これだけで「Retry」の前に「CountdownText」が見えるようになったかと思います。Unityでは同じCanvas内にある場合、Inspector上でより下にあるものが手前に表示されます。

そして「CountdownText」を適当に上に移動しておきましょう。これでカウントダウン時も、ゴール時も見える位置になりました。

またこの時「CountdownText」の「Text」コンポーネントで「RaycastTarget」のチェックを外しておきましょう。この「RaycastTarget」というのは文字や画像にあるもので、「Raycast」のターゲットにするかのフラグです。ボタンを押す時などUIをクリックやタップで操作する時には必ず「Raycast(レーザーのようなもの)」をクリック位置に放って、それにヒットしたUIを「クリックされた」とUnity内部で処理しています。

ボタンを押したりする必要のないUIでは、「RaycastTarget」をオフにしておくと押したいUIの前に別のUIが被って押せない、ということを防ぐことができるので意識しておくといいでしょう。

順位決定処理の追加

では、処理を追加していきましょう。まずは「CPUContorller.cs」を開いてください。

今CPUはゴールした時に止まってしまい、他の車の移動の邪魔になってしまうのでゴール後も動き続けるように修正も同時にやっていきます。

続きを読む

このコンテンツはパスワードで保護されています。 コンテンツを読みたい方はUnity入門の森ショップ(https://unityforest.stores.jp/)で講座閲覧権を取得してね。

次回に向けて

長くなりましたがこれで完了です。

Unityに戻ってゲームを開始してみましょう。

スタート→指定周回数を走る→ゴール&順位表示ができるようになっているかと思います。

これで一通りのゲームの完成です。今回はここまでにします。

次回は簡易的ではありますが、スマホで操作できるようにしていきます。

次回の記事 : 

Unity レースゲームの作り方9 スマホに移植してモバイルレーシングゲームを完成させる
本講座ではUnityとC#を使ってレースゲームを作る方法について解説しています。今回は第九回となります。 前回まででレースゲームに必要な一通りの機能を作成し、PCで操作できるようにしてきました。 前回の記事 : 今回は簡易的ではあ...

 

Unityレースゲームの作り方チュートリアル講座に戻る>>



Unity入門の森オリジナル本格ゲーム制作講座はこちら
7種類の本格ゲームの全ソースコード公開・画像&動画による解説付き

コメント

タイトルとURLをコピーしました