3Dシューティングゲームで、写真のようなシールドを作成しました。
8枚の板(Quad)を角度を変えて組み合わせてあります。これに大き目の物体が当たるとき、場合によって1回~3回、「当たった」という判定が出ます。継ぎ目辺りにぶつかったとき(複数枚に同時に当たったとき)、Quadそれぞれにアタッチしたスクリプト内で「当たった!」ということになるのでしょう。しかし当たったらすぐに物体のゲームオブジェクトは削除していますから、納得いきません。
そこで実験してみました。状況はやや変わりますが、同じ大きさのQuad(Unityの3Dオブジェクト)を2枚、重ねます。この2枚に、弾が当たったら即、その弾を削除(Destroy())するスクリプトをアタッチし、当たったらDebug.Log("当たり")を実行するようにします。このとき、弾が当たるとどうなるでしょうか?
2回「当たった」ことになりました。サイトをあちこち調べると、どうやらゲームオブジェクトはDestroy()で即、削除されるわけではなく、Destroy()が呼ばれたフレームの最後で削除されるのだそう。理屈は分かりましたが、このままではスコアが2回加算されてしまうなど、やはりまずいです。仕方がないのでメインのスクリプト内に当たった物体のゲームオブジェクトを保存し、次回の当たりでもし同じゲームオブジェクトだったら無視、としたら解決しました。シールドの形状などによっては、ゲームオブジェクトは3つくらい保存した方が確実でしょう。
追記:
写真のシールドは一見8枚ですが、(裏から見ると透けて見えて都合が悪いので)裏返したQuadを貼り合わせており、実は2*8 = 16 枚です。最初にこれを書くと読者の皆さんが混乱するかと思い、上のような記事にしました。裏返したQuadのコライダは外してあります。ですから、当たりの判定が複数回出るのは継ぎ目の関係です。