How do you continue movement after un-pausing

I have a simple 3d environment for playing around and I wanted to add a pausing feature.

Currently when I pause this game I set all game items to “RigidbodyConstraints.FreezeAll”

When I un-pause I set “RigidbodyConstraints.none” however movement of objects do not continue. I am assuming because when the Constraints.FreezeAll is activated all the velocities are set to 0.

How would I resume the velocity is the same direction it was previous traveling.
I have tried saving the velocity of all moving objects and then applying them back to it when unfrozen but have had no luck.
Here is my code:

public void puaseGame()
{
    if (round)
    {
         weaponMovments = new ArrayList();
         ballMovments = new ArrayList();
         GameObject[] Balls = GameObject.FindGameObjectsWithTag("Ball");
         GameObject[] weapons = GameObject.FindGameObjectsWithTag("weapon");
         OpenDoors = !OpenDoors;
         if (OpenDoors)
         {
             for(int i =0;i<weapons.Length;i++)
             {
                  weapons[i].GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
                  weapons[i].GetComponent<Rigidbody>().AddForce((Vector3)weaponMovments[i]);
             }
             for (int i = 0; i < Balls.Length; i++)
             {
                  Balls[i].GetComponent<Rigidbody>().constraints = RigidbodyConstraints.None;
                  Balls[i].GetComponent<Rigidbody>().AddForce((Vector3)ballMovments[i]);
              }
           }
           else
           {
              foreach (GameObject weapon in weapons)
              {
                   weaponMovments.Add(new Vector3(weapon.GetComponent<Rigidbody>().velocity.x, weapon.GetComponent<Rigidbody>().velocity.y, weapon.GetComponent<Rigidbody>().velocity.z));
                   //weaponMovmentsM.Add(weapon.GetComponent<Rigidbody>().velocity.magnitude);
                   weapon.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll;
               } 
               foreach (GameObject ball in Balls)
               {
                   ballMovments.Add(new Vector3(ball.GetComponent<Rigidbody>().velocity.x, ball.GetComponent<Rigidbody>().velocity.y, ball.GetComponent<Rigidbody>().velocity.z));
                   //ballMovmentsM.Add(ball.GetComponent<Rigidbody>().velocity.magnitude);
                   ball.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll;
               }
            }
       }
}

Don’t do it with constraints, just set Time.timescale to 0 and unpause it by resetting it to 1 (can also do fast/slowmotion).

2 Likes

here’s an attempt to do what you want I used a dictionary, I didn’t even test if it compiles but It should be good i think.

BTW, when you do

weaponMovments.Add(new Vector3(weapon.GetComponent<Rigidbody>().velocity.x, weapon.GetComponent<Rigidbody>().velocity.y, weapon.GetComponent<Rigidbody>().velocity.z)));

velocity is already a vector 3 and you’re creating an identical vector, just go

weaponMovments.Add(weapon.GetComponent<Rigidbody>().velocity);
public class PauseManager : MonoBehaviour {

    Dictionary<Rigidbody, Vector3> rb2vel;

    void Pause() {

        rb2vel = new Dictionary<Rigidbody, Vector3>();
        GameObject[] balls = GameObject.FindGameObjectsWithTag("Ball");
        GameObject[] weapons = GameObject.FindGameObjectsWithTag("weapon");

        for (int i = 0; i < balls.Length; i++)
            rb2vel.Add(balls[i].GetComponent<Rigidbody>(), balls[i].GetComponent<Rigidbody>().velocity);

        for (int i = 0; i < weapons.Length; i++)
            rb2vel.Add(weapons[i].GetComponent<Rigidbody>(), weapons[i].GetComponent<Rigidbody>().velocity);

    }

    void Unpause() {

        GameObject[] balls = GameObject.FindGameObjectsWithTag("Ball");
        GameObject[] weapons = GameObject.FindGameObjectsWithTag("weapon");
     
        for (int i = 0; i < balls.Length; i++)
            if (rb2vel.ContainsKey(balls[i].GetComponent<Rigidbody>()))
                balls[i].GetComponent<Rigidbody>().velocity = rb2vel[balls[i].GetComponent<Rigidbody>()];

        for (int i = 0; i < weapons.Length; i++)
            if (rb2vel.ContainsKey(weapons[i].GetComponent<Rigidbody>()))
                weapons[i].GetComponent<Rigidbody>().velocity = rb2vel[weapons[i].GetComponent<Rigidbody>()];

    }
}
1 Like

Thank you very much for the help and suggestions. Sorry I didn’t get back to you sooner. I have been away but I have tried your suggestions but there is an issue with it. I cant set the time scale to 0 as this is a VR time and I wanted the player to be able in interact with a menu when paused. Can I only set the Time scale for specific objects?

Thank you, Using the Pause method you posted above I was able to rig it to work with constrains and an addforce method with pause.!

The regular UI is uneffected by time scale and I don’t have VR so I can’t tell ya try asking in the VR forum

No worries man. You still managed to help me a lot!

Also if you end up using the script I posted rather then using time scale you also need to save the angular velocity, without it object will lose all spin when pausing.