Init
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f65318ec993bd7418c7fcc273b47e69
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,177 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor.SceneManagement;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class PlaySpeedToolbar
|
||||
{
|
||||
private const string ToolbarElementName = "PlaySpeedToolbar";
|
||||
private const double ToolbarCheckInterval = 0.25;
|
||||
|
||||
private static readonly float[] Speeds = { 1f, 2f, 4f };
|
||||
|
||||
private static VisualElement toolbarElement;
|
||||
private static double nextToolbarCheckTime;
|
||||
|
||||
static PlaySpeedToolbar()
|
||||
{
|
||||
EditorApplication.update += OnEditorUpdate;
|
||||
EditorApplication.playModeStateChanged += OnPlayModeChanged;
|
||||
EditorApplication.delayCall += AddToolbarUI;
|
||||
AssemblyReloadEvents.afterAssemblyReload += OnAfterAssemblyReload;
|
||||
}
|
||||
|
||||
private static void OnAfterAssemblyReload()
|
||||
{
|
||||
EditorApplication.delayCall += AddToolbarUI;
|
||||
}
|
||||
|
||||
private static void OnPlayModeChanged(PlayModeStateChange state)
|
||||
{
|
||||
if (state == PlayModeStateChange.EnteredEditMode)
|
||||
Time.timeScale = 1f;
|
||||
|
||||
EditorApplication.delayCall += AddToolbarUI;
|
||||
}
|
||||
|
||||
private static void OnEditorUpdate()
|
||||
{
|
||||
EnsureToolbarExists();
|
||||
}
|
||||
|
||||
private static void EnsureToolbarExists()
|
||||
{
|
||||
if (EditorApplication.timeSinceStartup < nextToolbarCheckTime)
|
||||
return;
|
||||
|
||||
nextToolbarCheckTime = EditorApplication.timeSinceStartup + ToolbarCheckInterval;
|
||||
|
||||
var toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
|
||||
if (toolbarType == null)
|
||||
return;
|
||||
|
||||
var toolbars = Resources.FindObjectsOfTypeAll(toolbarType);
|
||||
if (toolbars == null || toolbars.Length == 0)
|
||||
return;
|
||||
|
||||
foreach (var toolbar in toolbars)
|
||||
{
|
||||
TryInjectIntoToolbar(toolbarType, toolbar);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddToolbarUI()
|
||||
{
|
||||
var toolbarType = typeof(Editor).Assembly.GetType("UnityEditor.Toolbar");
|
||||
if (toolbarType == null)
|
||||
return;
|
||||
|
||||
var toolbars = Resources.FindObjectsOfTypeAll(toolbarType);
|
||||
if (toolbars == null || toolbars.Length == 0)
|
||||
return;
|
||||
|
||||
foreach (var toolbar in toolbars)
|
||||
{
|
||||
TryInjectIntoToolbar(toolbarType, toolbar);
|
||||
}
|
||||
}
|
||||
|
||||
private static void TryInjectIntoToolbar(Type toolbarType, UnityEngine.Object toolbar)
|
||||
{
|
||||
var rootField = toolbarType.GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (rootField == null)
|
||||
return;
|
||||
|
||||
if (rootField.GetValue(toolbar) is not VisualElement root)
|
||||
return;
|
||||
|
||||
// Центр тулбара, рядом с play/pause/stop
|
||||
var middleContainer = root.Q("ToolbarZonePlayMode");
|
||||
if (middleContainer == null)
|
||||
return;
|
||||
|
||||
var existing = middleContainer.Q<IMGUIContainer>(ToolbarElementName);
|
||||
if (existing != null)
|
||||
{
|
||||
toolbarElement = existing;
|
||||
return;
|
||||
}
|
||||
|
||||
var newElement = new IMGUIContainer(DrawGUI);
|
||||
newElement.name = ToolbarElementName;
|
||||
newElement.style.flexGrow = 0;
|
||||
newElement.style.flexShrink = 0;
|
||||
newElement.style.marginLeft = 6;
|
||||
newElement.style.marginRight = 2;
|
||||
newElement.style.minWidth = 118;
|
||||
newElement.style.maxWidth = 140;
|
||||
|
||||
middleContainer.Add(newElement);
|
||||
toolbarElement = newElement;
|
||||
}
|
||||
|
||||
private static void DrawGUI()
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
// Bootstrap toggle
|
||||
bool bootstrapEnabled = SceneBootstrapLoader.Enabled;
|
||||
|
||||
Color oldBg = GUI.backgroundColor;
|
||||
if (bootstrapEnabled)
|
||||
GUI.backgroundColor = new Color(0.72f, 0.84f, 1f);
|
||||
|
||||
if (GUILayout.Button(
|
||||
new GUIContent("B", bootstrapEnabled ? "Bootstrap: ON" : "Bootstrap: OFF"),
|
||||
EditorStyles.miniButtonLeft,
|
||||
GUILayout.Width(24),
|
||||
GUILayout.Height(18)))
|
||||
{
|
||||
SceneBootstrapLoader.Enabled = !SceneBootstrapLoader.Enabled;
|
||||
|
||||
if (!SceneBootstrapLoader.Enabled)
|
||||
EditorSceneManager.playModeStartScene = null;
|
||||
}
|
||||
|
||||
GUI.backgroundColor = oldBg;
|
||||
|
||||
bool isPlaying = EditorApplication.isPlaying;
|
||||
EditorGUI.BeginDisabledGroup(!isPlaying);
|
||||
|
||||
for (int i = 0; i < Speeds.Length; i++)
|
||||
{
|
||||
float speed = Speeds[i];
|
||||
bool selected = Mathf.Approximately(Time.timeScale, speed);
|
||||
|
||||
GUIStyle buttonStyle;
|
||||
if (i == Speeds.Length - 1)
|
||||
buttonStyle = EditorStyles.miniButtonRight;
|
||||
else
|
||||
buttonStyle = EditorStyles.miniButtonMid;
|
||||
|
||||
oldBg = GUI.backgroundColor;
|
||||
if (selected)
|
||||
GUI.backgroundColor = new Color(0.72f, 0.84f, 1f);
|
||||
|
||||
if (GUILayout.Button(
|
||||
new GUIContent($"{speed:0}x", $"Set Time.timeScale = {speed}"),
|
||||
buttonStyle,
|
||||
GUILayout.Width(24),
|
||||
GUILayout.Height(18)))
|
||||
{
|
||||
Time.timeScale = speed;
|
||||
}
|
||||
|
||||
GUI.backgroundColor = oldBg;
|
||||
}
|
||||
|
||||
EditorGUI.EndDisabledGroup();
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 78b0762537f106d43858a89548fe370b
|
||||
Reference in New Issue
Block a user