質問: スマホ用のパズルアプリを制作しております初心者です。(Unity5.6使用) パズルピースをドラッグドロップで、 正解の位置のスロットにはめ込むというゲーム内容です。 (70個程のパズルピースがあります) OnTriggerEnter2Dで接触判定しております。 パズルピースと正解スロットとの接触があった場合、以下の3つの命令を同時に実行しております。 --- 1. パズルピースオブジェクトの一部分をDestroy 2. スロットオブジェクトの添付スクリプトをDestroy 3. パズルピースオブジェクトの添付スクリプトをDestroy --- **問題点** たいていの場合、3つの命令は問題なく作動するのですが、 だいたい数十回に1回ほどですが、接触判定後の上記の3つの命令が全て無視されます。 **その他の問題の詳細** * PC上(MAC)でもスマホ実機上でも起こります * パズルピースが70個のシーンでこの問題が起こり、パズルピースが10個のみのシーンでは起こらないようです。 * パズルピースのRigidbodyの「Sleeping Mode」を「Start Awake」にしても「Never Sleep」にしても起こります 無視された場合は、パズルピースをもう一度ドラッグし直して、 再び同じ位置のスロットにはめ直しをすると、3つの命令は実行されます。 --- **対策(やってみた事)** 接触判定が無視されてしまう事に対しての対策として、 FixedUpdate内にも、接触判定時と同様の上記の3つのの命令を入れました。 (もし削除希望のオブジェクトが残っていた場合に、実行されるように設定しました。) ※常時FixedUpdate内で判定を連続するとメモリ消費が大きいと思われるので、 フラグがtrueの時のみに判定を実行されるようにしております。 (ドラッグ終了時点でフラグをtrue、0.3秒後にフラッグをfalseと設定)) その結果、FixedUpdate内の命令が効いているようで、 接触判定が無視されることはなくなったようです。 (それによりRigitbody2DのSleeping ModeをStart Asleepにしました 「Start Asleep」がもっともメモリ消費が少ないと思われるので) --- **質問** 2重に(OnTriggerEnter2DとFixedUpdate)で同じDestroyの命令を実行することに 不安を感じております。この方法はやはりおかしいでしょうか? (ログを確認すると先にFixedUpdate内の命令が実行されているようで、 実際には、FixedUpdateのみが効いていて、OnTriggerEnter2Dの命令は効いてないと思われます) 何か別の方法はありませんでしょうか? UpdateおよびFixedUpdateは遅く、メモリ消費も心配なので、できればUpdate、FixedUpdateを使用せずに OnTriggerEnter2Dで確実に命令が実行される方法はないでしょうか? すいませんが、ご教授よろしくおねがいいたします。 --- **追記(やってみた事2)** 「OnTriggerEnter2D」を「OnTriggerStay2D」に変更し、FixedUpdateの命令をやめてみましたが、 それでもまだ、ごくたまに上記1〜3の命令が、無視はされなくなったようですが、 命令実行のタイミングが若干遅れる事があります。 ※さらに「FixedUpdateで上記1~3の命令を実行する場合」と、 「OnTriggerStay2Dで実行する場合」を比較すると「OnTriggerStay2D」の方が 多くメモリ消費しています。(大幅な差はありませんが) (常時命令が呼び出されないように両方の方法ともに、フラグで命令の実行時間を制限しております) ※Rigidbody2Dの「Collision Detection」は「Continous」、 「Sleeping mode」は「Never sleep」に設定しております。 再度考えましたが、 シンプルなドラッグドロップのパズルゲームで、 静止してるスロットにパズルピースをドラッグして重ねるだけなので、 理論的には「OnTriggerStay2D」ではなく 最初に「OnTriggerEnter2D」で重なった瞬間のみ判定するほうが、 正しいような気がしております。 どうにか「OnTriggerEnter2D」で確実に命令を実行させる方法なないものでしょうか? ご教授よろしくおねがいいたします。
回答: **追記 / 自己解決しました** あくまで当方の予測ですが、70個のパズルピースがあるという事により、 Unityの処理が追いつかない部分があり、そのせいで命令が無視されるのではないか、と思われます。 (パズルピースが10個ほどのシーンではこの問題は起こっておりません。) **解決方法** **OnTriggerEnter2D**使用で、 コライダーの形を「BoxCollider2D」から**「CircleCollider2D」**に変えました。 理由は、いくつかのサイトで「CircleCollider2D」の方が、最もシンプルな処理で、 「BoxCollider2D」より処理が早いとの記述があった為です。 さらに、スロット側、パズルピース側の 両方のコライダーの判定範囲の半径を共に最小数値の**「0.0001」**に変えました。 (この数値が大きくなると上記の判定無視が起こってしまいます。) ※ Rigidbody2D「Collision Detection」は**「Continous」、「Discrete」**両方共に動作します。 ※ Rigidbody2D「Sleeping Mode」は**「Never Sleep」**に設定しております。 ※ 上記のFixedUpdate内での衝突判定の処理は削除しました。 何度も設定を変えて実験しましたが、 70個のパスルピースがあるという、この私の状況では、 上記の設定でなければ、うまく作動しない模様です。 閲覧いただき、ありがとうございました。