Skip to content

Instantly share code, notes, and snippets.

@jasielmacedo
Last active June 16, 2023 19:51
Show Gist options
  • Save jasielmacedo/c5391fd145572bebbe2b5052e3a38495 to your computer and use it in GitHub Desktop.
Save jasielmacedo/c5391fd145572bebbe2b5052e3a38495 to your computer and use it in GitHub Desktop.
To Test Physics on Editor Without play - Unity Engine 2017
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;
}
}
}
@ms502040
Copy link

ms502040 commented Apr 8, 2023

Awesome!

@jtwbellian
Copy link

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