Pausing a game works relatively easy, you just have to implement a check method to all your objects that would move - do not play around with the actual time.timeScale!
Now implementing that works relatively easy, one gameObject where you have a simple boolean attached to and include a method to switch it around. When its true your game should be running when its false it should be paused.
Then on every gameobject needed include a line that will check if that boolean is true or false (GameObject.GetComponent(). == true/false). Should you use rigidbodies I also would use a method to set them all kinematic or static for a moment.
You should definitely set Time.timeScale to 0 to make everything stop and set it back to 1 (or whatever it was before) when continuing. Putting a bool in every single object that moves will get super messy very quickly. You will also have to remember to put it into every new object.
Especially when using physics it gets pretty complicated to stop them all and let them continue afterwards as if nothing happened without using Time.timeScale. I don’t think (haven’t verified this) using isKinematic will keep the current velocity, so it is no replacement either.
When using timeScale you will only have to switch to using Time.unscaledTime for everything that should continue while the game is paused. There also is no need to iterate over all bodies of the scene.
I am using this in a game with some physics (including the player himself) and can pause/continue without a problem, even in mid-jump.
PS: It might still be necessary to react to the pause mode for scripts that do something other than just move using the deltaTime. I am using a stack of interaction modes onto which I push the menu mode when opening the menu and pop it again when closing the menu. A simple code line at the beginning of the Update() methods like this will probably suffice, though:
if (Time.timeDelta < Mathf.Epsilon) return;
Now some actual remarks concerning your code:
You don’t need a coroutine, you should not even process input in one or repeatedly start it in your Update() method.
Without writing out the concrete code, I will just list the things I would do:
Add a method ShowNote(bool show) that will:
Make note visible/invisible if show is true/false
set Time.timeScale = show ? 0 : 1
set isActive = show; to keep track of the current state
Add a OnTriggerEnter() that will cause the note to pop up, call ShowNote(true) here
in Update() add if(Input.GetKeyDown(KeyCode.Escape) && isActive) ShowNote(false); to hide the note again
A big thank you! Do you know what was my mistake ? I have a pause menu on a GameObject . I disabled it and now your script works great! Thank you very much. But how do I make my pause menu works even if Time.timeScale is already there for the system note
My PauseMenu Script: