daily pastebin goal
72%
SHARE
TWEET

StopPhysics.cs

mvaganov Oct 15th, 2016 (edited) 71 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEngine;
  2.  
  3. /// <summary>A utility script to pause and unpause active elements in a Unity game
  4. /// Latest version at: https://pastebin.com/FaT6i5yF </summary>
  5. /// <description>MIT License - TL;DR - This code is free, don't bother me about it!</description>
  6. /// <author email="mvaganov@hotmail.com">Michael Vaganov</author>
  7. public class StopPhysics : MonoBehaviour {
  8.     /// <summary>keep track of an object's physics info</summary>
  9.     private struct Freeze {
  10.         public GameObject go;
  11.         public Vector3 v;
  12.         public Freeze(GameObject go){
  13.             this.go = go;
  14.             Rigidbody rb = go.GetComponent<Rigidbody>();
  15.             if (rb) {
  16.                 v=rb.velocity;
  17.                 rb.isKinematic=true;
  18.             } else {
  19.                 v = Vector3.zero;
  20.             }
  21.             Animation a = go.GetComponent<Animation>();
  22.             if(a) { a[a.clip.name].speed = 0; }
  23.         }
  24.         public void Unfreeze() {
  25.             Rigidbody rb = go.GetComponent<Rigidbody>();
  26.             if (rb) {
  27.                 rb.velocity = v;
  28.                 rb.isKinematic = false;
  29.             }
  30.             Animation a = go.GetComponent<Animation>();
  31.             if(a) { a[a.clip.name].speed = 1; }
  32.         }
  33.     }
  34.  
  35.     /// <summary>list of frozen things, saved before the objects are halted.</summary>
  36.     private static Freeze[] snapshot = null;
  37.  
  38.     /// <returns><c>true</c> if the physics is frozen; otherwise, <c>false</c>.</returns>
  39.     public static bool IsStopped() { return snapshot != null; }
  40.  
  41.     public void TogglePhysics() { StopPhysics.Toggle (); }
  42.  
  43.     public void disablePhysics() {
  44.         SetupIfNeeded ();
  45.         whenDeactivates.Invoke ();
  46.         DisablePhysics ();
  47.     }
  48.     public static void DisablePhysics() {
  49.         Rigidbody[] bodies = GameObject.FindObjectsOfType<Rigidbody> ();
  50.         Animation[] anims = GameObject.FindObjectsOfType<Animation> ();
  51.         snapshot = new Freeze[bodies.Length+anims.Length];
  52.         for (int i = 0; i < bodies.Length; ++i) { snapshot [i] = new Freeze(bodies [i].gameObject); }
  53.         for (int i = 0; i < anims.Length; ++i) { snapshot [bodies.Length+i] = new Freeze(anims [i].gameObject); }
  54.     }
  55.     public void enablePhysics() {
  56.         SetupIfNeeded ();
  57.         whenActivates.Invoke ();
  58.         EnablePhysics ();
  59.     }
  60.     public static void EnablePhysics() {
  61.         for (int i = 0; i < snapshot.Length; ++i) {
  62.             if (snapshot [i].go != null) {
  63.                 snapshot [i].Unfreeze();
  64.             }
  65.         }
  66.         snapshot = null;
  67.     }
  68.  
  69.     /// <summary>Toggles the rigibdody physics.</summary>
  70.     public static void Toggle() {
  71.         if (IsStopped ()) { EnablePhysics (); } else { DisablePhysics (); }
  72.     }
  73.     #region find-and-disable classes
  74.     public static System.Type GetType( string typeName ) {
  75.         // Try Type.GetType() first. This will work with types defined by the Mono runtime, in the same assembly as the caller, etc.
  76.         System.Type type = System.Type.GetType( typeName );
  77.         // If it worked, then we're done here
  78.         if( type != null ) return type;
  79.         // If we still haven't found the proper type, we can enumerate all of the loaded assemblies and see if any of them define the type
  80.         try{
  81.             var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly();
  82.             var referencedAssemblies = currentAssembly.GetReferencedAssemblies();
  83.             foreach( var assemblyName in referencedAssemblies ) {
  84.                 // Load the referenced assembly
  85.                 var assembly = System.Reflection.Assembly.Load( assemblyName );
  86.                 if( assembly != null ) {
  87.                     // See if that assembly defines the named type
  88.                     type = assembly.GetType( typeName );
  89.                     if( type != null ) return type;
  90.                 }
  91.             }
  92.         } catch (System.Exception){ }
  93.         // if the GetExecutingAssembly library call failed, possibly due to security constraints, try each known assembly individually
  94.         System.Reflection.Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies ();
  95.         for (int i = 0; i < assemblies.Length; ++i) {
  96.             type = assemblies [i].GetType (typeName);
  97.             if (type != null) return type;
  98.         }
  99.         // If the TypeName is a full name in an un-loaded assembly, then we can try loading the defining assembly directly
  100.         if( typeName.Contains( "." ) ) {
  101.             try{
  102.                 // Get the name of the assembly (Assumption is that we are using fully-qualified type names)
  103.                 var assemblyName = typeName.Substring( 0, typeName.IndexOf( '.' ) );
  104.                 // Attempt to load the indicated Assembly
  105.                 var assembly = System.Reflection.Assembly.Load( assemblyName );
  106.                 if( assembly == null ) return null;
  107.                 // Ask that assembly to return the proper Type
  108.                 type = assembly.GetType( typeName );
  109.                 if( type != null ) return type;
  110.             }catch(System.Exception ){}
  111.         }
  112.         // The type just couldn't be found...
  113.         return null;
  114.     }
  115.  
  116.     [Tooltip("Will search for a MonoBehaviours with the given complete name to disable.")]
  117.     public string[] classTypesToToggle = new string[]{
  118.         "UnityStandardAssets.Characters.FirstPerson.FirstPersonController",
  119.         "UnityStandardAssets.Characters.FirstPerson.RigidbodyFirstPersonController"
  120.     };
  121.     private System.Type[] knownTypes;
  122.     [Tooltip("When physics re-activates.")]
  123.     public UnityEngine.Events.UnityEvent whenActivates;
  124.     [Tooltip("When physics de-activates.")]
  125.     public UnityEngine.Events.UnityEvent whenDeactivates;
  126.  
  127.     private void SetupIfNeeded() {
  128.         if (knownTypes == null) { Setup (); }
  129.     }
  130.     private void Setup () {
  131.         knownTypes = null;
  132.         for (int i = 0; i < classTypesToToggle.Length; ++i) {
  133.             System.Type t = GetType(classTypesToToggle[i]);
  134.             if (t != null) {
  135.                 if (knownTypes == null) {
  136.                     knownTypes = new System.Type[classTypesToToggle.Length];
  137.                 }
  138.                 knownTypes [i] = t;
  139.             }
  140.         }
  141.         if (knownTypes != null) {
  142.             whenActivates.AddListener(()=>{SetEnabled (true);});
  143.             whenDeactivates.AddListener(()=>{SetEnabled (false);});
  144.         }
  145.     }
  146.     private void SetEnabledAllBehavioursOfType(System.Type type, bool enabled) {
  147.         if (type == null) return;
  148.         Object[] objs = GameObject.FindObjectsOfType (type);
  149.         for (int o = 0; o < objs .Length; ++o) {
  150.             Behaviour b = objs [o] as Behaviour;
  151.             if (b != null) {
  152.                 b.enabled = enabled;
  153.             }
  154.         }
  155.     }
  156.     public static void SetEnableMouse(bool enabled) {
  157.         Cursor.visible = !enabled;
  158.         Cursor.lockState = enabled ? CursorLockMode.Locked : CursorLockMode.None;
  159.     }
  160.     private void SetEnabled(bool enabled) {
  161.         if (knownTypes != null) {
  162.             for (int i = 0; i < knownTypes.Length; ++i) {
  163.                 if (knownTypes [i] != null) {
  164.                     SetEnabledAllBehavioursOfType (knownTypes [i], enabled);
  165.                 }
  166.             }
  167.         }
  168.         SetEnableMouse (enabled);
  169.     }
  170.     #endregion // find-and-disable classes
  171. }
RAW Paste Data
Top