Physics in scene editor mode?

Is there a way to apply gravity and physics to objects within the scene editor without running the game? I have some scenes that can be a bit complex when they start, as object may be slightly out of place until gravity affects them and they go to sleep. This can be a bit taxing when loading levels in iOS, and although only lasts a few seconds, I would prefer if everything is ready to go to sleep from the start.

Alternatively: if i start the game from the editor, I can create a prefab of objects in the position I want, but using this prefab to replace components breaks the original prefab relationship. Is there another way to save these objects positioning without using this scene prefab approach?

can't you just get the final testing position while in the editor, and then just make the objects start at the final resting position instead of waiting for them to settle?

I have been trying that but it gets insanely time consuming in large levels with many inclined floors with, sometimes up to a hundreads bodies (reason those levels get so bad at startup)

5 Answers

5

You can simulate physics in the editor by setting Physics.autoSimulation to false, and using Physics.Simulate() to advance physics frame by frame until your objects are settled.

Here is an example editor window:

using UnityEditor;
using UnityEngine;
  
public class ScenePhysicsTool : EditorWindow {
  
    private void OnGUI()
    {
        if (GUILayout.Button("Run Physics"))
        {
            StepPhysics();
        }
    }
  
    private void StepPhysics()
    {
        Physics.autoSimulation = false;
        Physics.Simulate(Time.fixedDeltaTime);
        Physics.autoSimulation = true;
    }
  
    [MenuItem("Tools/Scene Physics")]
    private static void OpenWindow()
    {
        GetWindow<ScenePhysicsTool>(false, "Physics", true);
    }
}

Yes, just drag the objects from the hierarchy to the project view during runtime. Or copy their transforms (with pen-and-paper or one of the tools you can get for that). You can then start the Rigidbodies Asleep.

Or just hit ctrl+c in play-mode, ctrl+v in edit mode and delete the original.

THAT! THATS what I needed! Darnit, such a simple answer and me here struggling with that!!! I got to admit, I would never had guessed the Unity editor was capable of copying that kind of information in the clipboard. Thank you!!! I guess I'll flag the answer you replied as the solution since you posted under it :) Thanks!

I see this is old but I use this asset: Editor Physics Simulator (2D & 3D) | Level Design | Unity Asset Store

Really simple and it lets you record animation clips of the physics simulations.

An improvement on @ThePilgrim 's answer:

using System;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace MysteryEditor
{
    public class EditorPhysicsSimulation : EditorWindow
    {
        bool isPlaying = false;

        private void OnEnable()
        {
            Undo.undoRedoEvent += undoRedoEvent;
        }

        private void OnDisable()
        {
            Undo.undoRedoEvent -= undoRedoEvent;
            Stop();
        }

        private void undoRedoEvent(in UndoRedoInfo undo)
        {
            Stop();
        }

        private void OnGUI()
        {
            if (isPlaying == false)
            {
                if (GUILayout.Button("►"))
                {
                    isPlaying = true;
                    RecordUndo();
                    EditorApplication.update += StepPhysics;
                }
            }
            else
            {
                if (GUILayout.Button("■")) Stop();
            }
        }

        void Stop()
        {
            isPlaying = false;
            EditorApplication.update -= StepPhysics;

            foreach (var rb in rigidbodies)
            {
                rb.angularVelocity = Vector3.zero;
                rb.linearVelocity = Vector3.zero;
            }
        }

        Rigidbody[] rigidbodies;

        void RecordUndo()
        {
            rigidbodies = GameObject.FindObjectsByType<Rigidbody>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
            var transforms = rigidbodies.Select(x => (UnityEngine.Object)x.transform).ToArray();
            Undo.RecordObjects(transforms, "Simulate Physics");
        }

        private void StepPhysics()
        {
            var simMode = Physics.simulationMode;
            Physics.simulationMode = SimulationMode.Script;
            Physics.Simulate(Time.fixedDeltaTime);
            Physics.simulationMode = simMode;

            foreach (var rb in rigidbodies)
                EditorUtility.SetDirty(rb.transform);
        }

        [MenuItem("Tools/Physics Simulator")]
        private static void OpenWindow()
        {
            GetWindow<EditorPhysicsSimulation>(false, "Physics", true);
        }
    }
}

I don’t really know what you want to do , but I would press Play icon and go back to the scene editor window to see the physic in the editor

Yea, the editor scripting sounds interesting and I'll look more into them for my next project. But I think I'll go back to saving prefabs while within the editor, keeping a duplicate of the entire scene that has the original prefab associations. This was my "fallback" solution from the start but wanted to see if there was some built in feature I may had missed.