衝突の検出で色々と試行錯誤・・・ネットで見ても、以外に情報が少ない。
基本的な部分をおさらい。UnityではオブジェクトにRigidbodyをアタッチすると剛体として認識する。この剛体同士がぶつかると自動的に物理的な挙動を行うようになる。
ぶつかり、反発係数とか重量によって反発する。
コライダーを設定しておけば、ぶつかった後の処理も行える。ぶつかった時に、OnCollisionEnterが呼ばれる。そこに処理を記述しておけば、ぶつかった後の処理を設定できる。
ぶつかり続けていると、OnCollisionStayがフレーム毎に呼ばれる。
衝突が終わるとOnCollisionExitが呼ばれる。
ここで問題なのは、物理挙動が問題になる場合がある。物体同士がぶつかっても必ずしも物理的な動きをしてほしくない場合。
例えば、格闘ゲームなどでパンチやキックをして相手に当たって物理挙動で反発されても困る。単純な物理挙動では、ダメな場合は「IsTrigger」という項目にチェックを入れて物理挙動じゃないことを設定しないとダメ。
ここで呼ばれるのは、
OnTriggerEnter(衝突時) OnTriggerExit(離れた場合)OnTriggerStay(衝突している間)
と変化する。
ここまで理解してC#で処理を書いて実行してみると、なぜかOnTriggerStayがある回数以上呼ばれないことがわかった。
色々と調べて、処理も変更したけどダメ・・・そもそも、そこまで難しいロジックを組んでいないので、ある回数で処理が終わるなんておかしい・・・
更に調べてみるとUnityは処理を軽くするため、ぶつかり続けている場合には一定時間経過するとスリープモードになってしまうとか・・・
RigidBodyのSllepingModeを「NeverSleep」に変更して解決。
う~ん、ぶつかり続けるような処理はダメなんだろうな・・・
次に問題になったのは、OnTriggerExitが呼ばれない。これは、処理の中で一定の条件でオブジェクトを削除しているからだと思われる。
削除した場合は、離れたわけではないので呼ばれない?!?!
そこで、フレーム毎にぶつかっているものがあるか?という判定を行うようにしたい。
ここでも、Unityのリファレンスとのにらめっこ。
コライダーの関数で、「IsTouch」というのがあるので、試行錯誤。
色々調べて、試してみたら次の方法でうまくいった。
private PolygonCollider2D polygon2d;
private bool col;
void Start(){ polygon2d = this.GameObject.GetComponent<PolygonCOllider2D>();
}
void Update(){col = polygon2d.IsTouchingLayers();
}
省略している部分があるので、このままコピペしても動きません。
コライダーとして、ポリゴンコライダーの2D版を使っているので、ポリゴンコライダーをインスタンスして、スタートしたら、オブジェクトにアタッチされているポリゴンコライダーを呼び出して格納。
Updateで、毎フレームごとにアタッチされたコライダーに衝突しているものがあるか判定。
ここでは、レイヤーとして衝突しているものがあるか?判定している。これで、複数の物体の衝突も検出できる。
衝突している場合は、変数colにtrueが格納されるので、colの値で動作を決めることが出来る。
わかっているようで、わかっていない部分を今回も再認識できたような気がする。
これが、誰かの役にたてる内容であればいいけど。
スポンサーリンク