Last active
June 16, 2023 19:51
-
-
Save jasielmacedo/c5391fd145572bebbe2b5052e3a38495 to your computer and use it in GitHub Desktop.
To Test Physics on Editor Without play - Unity Engine 2017
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEditor; | |
// This causes the class' static constructor to be called on load and on starting playmode | |
[InitializeOnLoad] | |
class PhysicsSettler | |
{ | |
// only ever register once | |
static bool registered = false; | |
// are we actively settling physics in our scene | |
static bool active = false; | |
// the work list of rigid bodies we can find loaded up | |
static Rigidbody[] workList; | |
// we need to disable auto simulation to manually tick physics | |
static bool cachedAutoSimulation; | |
// how long do we run physics for before we give up getting things to sleep | |
const float timeToSettle = 10f; | |
// how long have we been running | |
static float activeTime = 0f; | |
// this is the static constructor called by [InitializeOnLoad] | |
static PhysicsSettler() | |
{ | |
if (!registered) | |
{ | |
// hook into the editor update | |
EditorApplication.update += Update; | |
// and the scene view OnGui | |
SceneView.onSceneGUIDelegate += OnSceneGUI; | |
registered = true; | |
} | |
} | |
// let users turn on | |
[MenuItem("GameMenu/Settle Physics")] | |
static void Activate() | |
{ | |
if( !active ) | |
{ | |
active = true; | |
// Normally avoid Find functions, but this is editor time and only happens once | |
workList = Object.FindObjectsOfType<Rigidbody>(); | |
// we will need to ensure autoSimulation is off to manually tick physics | |
cachedAutoSimulation = Physics.autoSimulation; | |
activeTime = 0f; | |
// make sure that all rigidbodies are awake so they will actively settle against changed geometry. | |
foreach( Rigidbody body in workList ) | |
{ | |
body.WakeUp(); | |
} | |
} | |
} | |
// grey out the menu item while we are settling physics | |
[MenuItem("GameMenu/Settle Physics", true)] | |
static bool checkMenu() | |
{ | |
return !active; | |
} | |
static void Update() | |
{ | |
if( active ) | |
{ | |
activeTime += Time.deltaTime; | |
// make sure we are not autosimulating | |
Physics.autoSimulation = false; | |
// see if all our | |
bool allSleeping = true; | |
foreach( Rigidbody body in workList ) | |
{ | |
if( body != null ) | |
{ | |
allSleeping &= body.IsSleeping(); | |
} | |
} | |
if( allSleeping || activeTime >= timeToSettle) | |
{ | |
Physics.autoSimulation = cachedAutoSimulation; | |
active = false; | |
} | |
else | |
{ | |
Physics.Simulate(Time.deltaTime); | |
} | |
} | |
} | |
static void OnSceneGUI(SceneView sceneView) | |
{ | |
if( active ) | |
{ | |
Handles.BeginGUI(); | |
Color cacheColor = GUI.color; | |
GUI.color = Color.red; | |
GUILayout.Label("Simulating Physics.", GUI.skin.box, GUILayout.Width(200)); | |
GUILayout.Label(string.Format("Time Remaining: {0:F2}",(timeToSettle - activeTime)), GUI.skin.box, GUILayout.Width(200)); | |
Handles.EndGUI(); | |
foreach( Rigidbody body in workList ) | |
{ | |
if( body != null ) | |
{ | |
bool isSleeping = body.IsSleeping(); | |
if( !isSleeping ) | |
{ | |
GUI.color = Color.green; | |
Handles.Label(body.transform.position, "SIMULATING"); | |
} | |
} | |
} | |
GUI.color = cacheColor; | |
} | |
} | |
} |
Awesome!
Works for regular rigidbodies in most situations, however does not work with physics joints
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Super helpful. Thank you for sharing!
(though it works much better using Time.fixedDeltaTime)