質問: Input.GetKeyDown(KeyCode.Return); } void OnCollisionStay2D(Collision2D col) { if (enter) { Debug.Log("やったね!"); } } //ダメだったパターン2 void OnCollisionStay2D(Collision2D col) { if (Input.GetkeyDown(Keycode.Return)) { Debug.Log("やったね!"); } } ``` 質問ばかりで申し訳ありませんが、どなたかわかる方がいれば、よろしくお願いします。
回答: 反応しないときがあるという件ですが、動く方のオブジェクトのSleeping Modeが「Start Awake」だとすると、オブジェクトに動きがなければスリープ状態になって物理計算が省略され、この時は両オブジェクトが接触していてもOnCollisionStay2Dは実行されなくなるようです。モードを「Never Sleep」にするとスリープしてしまうのを防げるかと思います。 OnCollisionStay2D内でのGetKeyDownについては、これもFixedUpdate内での場合と同じく避けるべきではないでしょうか? Unity - Manual: Execution Order of Event Functionsの「Script Lifecycle Flowchart」の図を見ますと、OnCollision系メソッドの実行タイミングは物理状態更新ループの後半に組み込まれており、試してみたところFixedUpdateと同様に1フレーム中で複数回実行されうるもののようでした。 また、Unity - Scripting API: Inputには > > Note also that the Input flags are not reset until "Update()", so its suggested you make all the Input Calls in the Update Loop. > > > *Inputフラグは「Update()」までリセットされないため、すべてのInput呼び出しはUpdateループ内で行うことが推奨されます。* との記述がありました。「ダメだったパターン2」をこれらに照らし合わせて考えてみると、1回キーを押しただけなのに複数回「やったね!」が表示されてしまうといったことがあるかもしれません。 「ダメだったパターン1」はOnCollisionStay2D内ではGetKeyDownを使用していないものの、`enter`がtrueの間にOnCollisionStay2Dが実行される回数が1回とは限らないことを考慮すると、やはり複数回「やったね!」が表示される現象が起こりうるものと思います。 関係を逆にして、衝突しているかどうかの方をboolで表現し、Update内で「衝突している」かつ「キー押下があった」場合に「やったね!」を表示するというのはどうでしょうか? ``` bool isColliding; void Update() { if (isColliding && Input.GetKeyDown(KeyCode.Return)) { Debug.Log("やったね!"); } } void OnCollisionEnter2D(Collision2D col) { Debug.Log("Enter"); isColliding = true; } void OnCollisionExit2D(Collision2D col) { Debug.Log("Exit"); isColliding = false; } ```