MaximilianPs

PhysicsSimulationWindow

Aug 17th, 2024 (edited)
774
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.50 KB | Source Code | 0 0
  1. // Save this class inside a folder called "Editor" (without quotation you know)
  2. // and also the file MUST be called PhysicsSimulationWindow.cs
  3.  
  4. using UnityEngine;
  5. using UnityEditor;
  6. using System.Collections.Generic;
  7. using UnityEditor.SceneManagement;
  8.  
  9. public class PhysicsSimulationWindow : EditorWindow
  10. {
  11.     private bool isSimulating = false;
  12.     private float simulationTime = 0f;
  13.     private float simulationDuration = 5f;
  14.     private SimulationMode originalSimulationMode;
  15.     private List<GameObject> selectedObjects = new List<GameObject>();
  16.     private List<Rigidbody> addedRigidbodies = new List<Rigidbody>();
  17.     private Vector2 scrollPosition;
  18.  
  19.     [MenuItem("Tools/Physics Simulation")]
  20.     public static void ShowWindow()
  21.     {
  22.         GetWindow<PhysicsSimulationWindow>("Physics Simulation");
  23.     }
  24.  
  25.     private void OnEnable()
  26.     {
  27.         Selection.selectionChanged += Repaint;
  28.     }
  29.  
  30.     private void OnDisable()
  31.     {
  32.         Selection.selectionChanged -= Repaint;
  33.     }
  34.  
  35.  
  36.     private void OnGUI()
  37.     {
  38.         UpdateSelectedObjects();
  39.  
  40.         GUILayout.Label("Selected Objects", EditorStyles.boldLabel);
  41.  
  42.         if (IsPrefabMode())
  43.         {
  44.             EditorGUILayout.HelpBox("Physics simulation is not available in the prefab editor. Please return to the main scene.", MessageType.Warning);
  45.             return;
  46.         }
  47.  
  48.         EditorGUI.BeginDisabledGroup(isSimulating);
  49.         simulationDuration = EditorGUILayout.FloatField("Simulation Time:", simulationDuration);
  50.         EditorGUI.EndDisabledGroup();
  51.  
  52.         if (GUILayout.Button(isSimulating ? "Stop Simulation" : "Start Simulation"))
  53.         {
  54.             if (isSimulating)
  55.             {
  56.                 StopSimulation();
  57.             }
  58.             else
  59.             {
  60.                 StartSimulation();
  61.             }
  62.         }
  63.  
  64.         if (isSimulating)
  65.         {
  66.             EditorGUILayout.LabelField($"Simulation Time: {simulationTime:F2}s / {simulationDuration:F2}s");
  67.         }
  68.  
  69.         GUILayout.Space(10);
  70.         GUILayout.Label("Selected Objects:", EditorStyles.boldLabel);
  71.  
  72.         scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(150));
  73.         foreach (var obj in selectedObjects)
  74.         {
  75.             EditorGUILayout.ObjectField(obj, typeof(GameObject), true);
  76.         }
  77.         EditorGUILayout.EndScrollView();
  78.     }
  79.  
  80.     private void UpdateSelectedObjects()
  81.     {
  82.         selectedObjects.Clear();
  83.         selectedObjects.AddRange(Selection.gameObjects);
  84.     }
  85.  
  86.     private bool IsPrefabMode()
  87.     {
  88.         return PrefabStageUtility.GetCurrentPrefabStage() != null;
  89.     }
  90.  
  91.     private void StartSimulation()
  92.     {
  93.         if (isSimulating || IsPrefabMode()) return;
  94.  
  95.         selectedObjects.Clear();
  96.         addedRigidbodies.Clear();
  97.         selectedObjects.AddRange(Selection.gameObjects);
  98.  
  99.         if (selectedObjects.Count == 0)
  100.         {
  101.             EditorUtility.DisplayDialog("No objects selected", "Select at least one object in the scene.", "OK");
  102.             return;
  103.         }
  104.  
  105.         foreach (var obj in selectedObjects)
  106.         {
  107.             Rigidbody rb = obj.GetComponent<Rigidbody>();
  108.             if (rb == null)
  109.             {
  110.                 rb = Undo.AddComponent<Rigidbody>(obj);
  111.                 addedRigidbodies.Add(rb);
  112.             }
  113.         }
  114.  
  115.         isSimulating = true;
  116.         simulationTime = 0f;
  117.         originalSimulationMode = Physics.simulationMode;
  118.         EditorApplication.update += SimulatePhysics;
  119.     }
  120.  
  121.     private void StopSimulation()
  122.     {
  123.         if (!isSimulating) return;
  124.  
  125.         isSimulating = false;
  126.         EditorApplication.update -= SimulatePhysics;
  127.         Physics.simulationMode = originalSimulationMode;
  128.  
  129.         foreach (var rb in addedRigidbodies)
  130.         {
  131.             if (rb != null)
  132.             {
  133.                 Undo.DestroyObjectImmediate(rb);
  134.             }
  135.         }
  136.         addedRigidbodies.Clear();
  137.  
  138.         SceneView.RepaintAll();
  139.     }
  140.  
  141.     private void SimulatePhysics()
  142.     {
  143.         if (!isSimulating) return;
  144.  
  145.         Physics.simulationMode = SimulationMode.Script;
  146.         Physics.Simulate(Time.fixedDeltaTime);
  147.  
  148.         simulationTime += Time.fixedDeltaTime;
  149.         SceneView.RepaintAll();
  150.  
  151.         if (simulationTime >= simulationDuration)
  152.         {
  153.             StopSimulation();
  154.         }
  155.  
  156.         Repaint();
  157.     }
  158.  
  159.     private void OnDestroy()
  160.     {
  161.         if (isSimulating)
  162.         {
  163.             StopSimulation();
  164.         }
  165.     }
  166. }
Advertisement
Comments
  • MaximilianPs
    1 year
    # text 0.13 KB | 0 0
    1. Save this class inside a folder called "Editor" (without quotation you know) and also the file MUST be called PhysicsSimulationWindow.cs
Add Comment
Please, Sign In to add comment