【TinyUnity】ProjectTiny0.21で当たり判定はどう変わった?

先月の終わりごろ、ProjectTiny0.20がアップデートされました。
晴れて0.21へと数字が進みました。
どのようなアップデートだったのかは以下の記事を参照してください。

大きな変更点としてはやはり、

Unity.Physicsに対応した

ということでしょう。

それに伴い、サンプルプロジェクトである TinyRacing もアップデートが行われました。

今回は、 Unity.Physics に対応した TinyRacing の当たり判定処理について解析していこうと思います。

ProjectTinySamples

https://github.com/Unity-Technologies/ProjectTinySamples

いや、そもそもUnity.Physicsって何?

恐らく、Unity.Physics自体をご存じない方も少なくないと思います。
そのため、ちょっとだけ概念自体の説明をしようと思います。

UnityPhysicsというのは、簡単に言ってしまえば

今までのUnityの物理演算よりも高速に動作する新たな物理演算システム

です。

UnityPhysicsはいわゆるDOTS用の物理演算システムになっています。

そのため、利用するにはある程度のDOTSの知識が必要となります。

実際はDOTSの解説から入るべきですが、流石に脱線し過ぎるのでこの記事ではこのくらいの解説に留めます。

そもそも、この記事を読んでいるということはProjectTinyに興味がある方だとおもいますので、おそらくDOTSは既にある程度理解されているかもしれませんね。

前バージョンのTinyRacingからの変更点

スクリプトがそれなりに変更されています。
具体的に言うと

今まで算術関数で当たり判定を行っていた部分がすべてリジェクト

コリジョンイベントがUnity.Physicsに対応したコードに変更

といった具合です。

これに伴って変更されたスクリプトは以下の通り

  • BumpCar.cs
  • EnterBoostPad.cs
  • CollideWalls.cs

どのように変化しているかは後述します。

EntityのComponentDataはどうなった?

これもUnity.Physics対応に伴って各所が変更されました。

分かりやすいのが道路とプレイヤーも含む車のEntityです。

車のEntity

前バージョン
今バージョン

ぱっと見で分かるかと思いますが、Unity.Physics用のColliderが付いています。
車の周りに見えるワイヤーフレームがColliderのShapeになっています。

車EntityにつけられているPhysicsShapeとPhysicsBody

正直、このあたりの仕様はUnity.Physicsを知らないとよくわからないと思います。
とりあえず、「あ、Colliderが使えるようになったからそうしたんだな」程度に捉えてください。
後日、Unity.Physicsに関する解説記事を書くことで補足しようと思っています。

道路のEntity

前バージョン
今バージョン

壁としての役割を持つ四角形のShapeが道路左右に置かれているのがワイヤーフレームから見て取れると思います。

なお、左右の壁は当たり判定用のメッシュが別途作られており、それをMeshColliderとして使用していました。

壁用のMesh

Systemはどう変わった?

TinyRacingで主な衝突イベントというのは

  • 他の車との衝突
  • フェンスへ衝突
  • ブーストパッドに乗る
  • オイルに乗る

大体この4つです。

今までこの4つは算術関数ですべて計算されていました。

そしてそれぞれの処理は以下のSystemが担当していました

対応表としては以下の通りです。

他の車との衝突 BumpCar.cs
フェンスへ衝突 CollideWalls.cs
ブーストパッドに乗る EnterBoostPad.cs
オイルに乗る EnterBoostPad.cs

ブーストパッド、オイルに乗った際のイベントは両方とも速度を加速、減速させるイベントのため、共通処理として実装されています。

使いまわすならEnterBoostPadってネーミングはどうなんだとは思いますが。

では、これが0.21でどう変わったかというと、以下のようになりました。

他の車との衝突 BumpCar.cs
フェンスへ衝突 削除
ブーストパッドに乗る EnterBoostPad.cs
オイルに乗る EnterBoostPad.cs

フェンスとの衝突処理が綺麗さっぱり無くなりました。


理由としてはUnity.Physicsの衝突処理がそれを補うようになったためです。

では他の2つのSystemは変化がないのかというと、そういうわけではないです。
むしろめちゃめちゃ変わりました。

まずは BumpCar.cs から見ていきましょう。

BumpCar.cs

ProjectTiny0.20

ProjectTiny0.21

0.20の頃はそれぞれのEntityの位置を取得して、距離を算出、一定距離以内であればヒット判定としていましたが、
0.21からUnity.Physicsに対応ICollisionEventsJobを用いてヒット判定を取得しています

次に EnterBoostPad.cs を見ていきましょう。

EnterBoostPad.cs

ProjectTiny0.20

ProjectTiny0.21

もう見るからに変わっています。

これもBumpCar.csと同様に
0.20の頃はそれぞれのEntityの位置を取得して、距離を算出、一定距離以内であればヒット判定としていましたが、
0.21からUnity.Physicsに対応となっています。

BumpCar.csと異なる点は ICollisionEventsJob ではなく、ITriggerEventsJob が使用されています。

これはColliderをTriggerとして設定している際に利用できます。

実際に、BoostPadやOilはTrigger設定されたColliderが設定されています。

今回からBoostPadにもUnity.Physicsが利用されている
Oilも同様
BoostPadのPhysicsShapeの設定
IsTriggerにチェックが入っていることがわかる

以上が、今回のアップデートで変化した当たり判定の処理になります。

まとめ

Unity.Physicsの比較的シンプルなサンプルコードとして優秀では?と思えるくらいにはシンプルな作りだと思います。

特定のEntityのヒット判定を識別するためのコードも中に入っているのでその点も含めて非常に優秀なUnity.Physicsのサンプルコードであると私は思いました。

個人的にはUnity.Physicsの対応で一気に作れる作品の幅が広がったので 結構ワクワクしています 。

しかしながら、この記事自体は
Unity.Physicsがそもそもわかんねぇよ!!!という方には非常に不親切な内容になってしまったかなと思います。

Unity.Physics自体はProjectTiny関係なく、DOTS向けの物理演算システムとして提供されているため、これを機会にUnity.Physicsの使い方を理解してみるのもいいかもしれません。

UnityPhysicsの解説記事は様々な有志の方がQiita等にて解りやすく執筆されていらっしゃいますから、それらを参考にしてみるといいと思います。