Sometimes there is a need to pause rigidbody simulation in Unity game. It can be done with Time.timeScale but it causes that all physics objects will be freezed so there should be a better way to stop game object. Effects of timeScale manipulation are also mentioned in one of our previous posts: FastTrick – Toast vs Time.timeScale – final battle! In this post we will show you how to pause rigidbody in two ways.
First, let’s consider what we need to pause rigidbody. The most important thing is to store its kinetic energy and freeze position. To achieve it we will create custom MonoBehaviour component which contains two methods: Pause and Resume. Look at code below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using UnityEngine; using System.Collections; [RequireComponent(typeof (Rigidbody))] // force Unity to add rigidbody component to game object public class RigidMono : MonoBehaviour { [HideInInspector] public bool rigidbodyPaused = false; // store information about rigibody state private Vector3 rigidbodyVelocity; // saved linear velocity private Vector3 rigidbodyAngularVelocity; // saved angular velocity private Rigidbody rigid; // our rigidbody reference void Awake () { rigid = GetComponent <Rigidbody> (); // get rigidbody in Awake } public void Pause () { rigidbodyVelocity = rigid.velocity; // save velocity rigidbodyAngularVelocity = rigid.angularVelocity; // save angular velocity rigid.isKinematic = true; // freeze rigidbody position and disable its simulation rigidbodyPaused = true; // update rb's state } public void Resume () { if (rigidbodyPaused) // check if rigidbody was paused { rigid.isKinematic = false; // unfreeze and enable simulation rigid.velocity = rigidbodyVelocity; // restore velocity rigid.angularVelocity = rigidbodyAngularVelocity; // restore angular velocity rigidbodyPaused = false; // update state } } } |
To make it work, just attach this script to game object which needs to be paused at runtime. We prepared a simple scene to show you how it works:
This scene contains few ball that continue to bounce. You can select specific ball and pause its moving and then resume. As you can see there are also two GUI elements: Button and Text. Note that Platform and Ball prefab contains adequate physics materials.
There are also two game objects: Spawner which instantiates balls with small delay and Test object which handles GUI elements changes and user screen touches. To see how they work just download full package and examine its scripts. Don’t forget to check project’s layers because in ball selection function we check only one layer which contains balls and nothing else. We also don’t want to have interactions between balls so look at Physics settings.
The second approach to pause rigidbody is to create extension methods for Rigidbody objects. This way is well presented by Justin Reinhart on his blog: Pause and UnPause a Rigidbody in Unity. It seems to be more elegant than our approach but also has a little less capabilities. You should decide which way better fits your needs 🙂
Download whole project with above codes, unzip and play! Share your ideas in comments below!