├── Editor.meta ├── Editor ├── SelectionHistory.cs ├── SelectionHistory.cs.meta ├── SelectionHistoryToolbarGUI.cs ├── SelectionHistoryToolbarGUI.cs.meta ├── UnityExtensions.SelectionHistory.Editor.asmdef └── UnityExtensions.SelectionHistory.Editor.asmdef.meta ├── LICENSE ├── LICENSE.meta ├── Menu-Items.png ├── Menu-Items.png.meta ├── README.md ├── README.md.meta ├── package.json └── package.json.meta /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dec90b06702ff47d288c9c7f8ff358b8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/SelectionHistory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using UnityEditor; 6 | using UnityEngine; 7 | 8 | #if UNITY_2019_1_OR_NEWER 9 | using UnityEngine.UIElements; 10 | #else 11 | using UnityEngine.Experimental.UIElements; 12 | #endif // UNITY_2018_1_OR_NEWER 13 | 14 | using Object = UnityEngine.Object; 15 | 16 | namespace UnityExtensions 17 | { 18 | 19 | public static class SelectionHistory 20 | { 21 | 22 | [Serializable] 23 | public struct SerializedSelection 24 | { 25 | public int[] instanceIDs; 26 | 27 | public SerializedSelection(Object[] selection) 28 | { 29 | instanceIDs = 30 | selection 31 | .Where(obj => obj != null) 32 | .Select(obj => obj.GetInstanceID()) 33 | .ToArray(); 34 | } 35 | 36 | public Object[] Deserialize() 37 | { 38 | return 39 | instanceIDs 40 | .Select(EditorUtility.InstanceIDToObject) 41 | .Where(obj => obj != null) 42 | .ToArray(); 43 | } 44 | } 45 | 46 | //---------------------------------------------------------------------- 47 | 48 | [Serializable] 49 | public struct SerializedHistory 50 | { 51 | private static string Key => 52 | $"UnityExtensions.SelectionHistory({Application.dataPath})"; 53 | 54 | public SerializedSelection[] backward; 55 | public SerializedSelection[] forward; 56 | 57 | public static void Save() 58 | { 59 | var history = new SerializedHistory 60 | { 61 | backward = Serialize(s_backward), 62 | forward = Serialize(s_forward), 63 | }; 64 | var json = JsonUtility.ToJson(history); 65 | EditorPrefs.SetString(Key, json); 66 | // Debug.Log("save: " + json); 67 | } 68 | 69 | public static void Load() 70 | { 71 | var json = EditorPrefs.GetString(Key, null); 72 | if (!string.IsNullOrEmpty(json)) 73 | { 74 | // Debug.Log("load: " + json); 75 | var history = JsonUtility.FromJson(json); 76 | s_backward.Clear(); 77 | s_backward.AddRange(Deserialize(history.backward)); 78 | s_forward.Clear(); 79 | s_forward.AddRange(Deserialize(history.forward)); 80 | } 81 | } 82 | 83 | private static SerializedSelection[] 84 | Serialize(List selections) 85 | { 86 | return 87 | selections 88 | .Select(selection => new SerializedSelection(selection)) 89 | .ToArray(); 90 | } 91 | 92 | private static IEnumerable 93 | Deserialize(SerializedSelection[] selections) 94 | { 95 | return 96 | selections 97 | .Select(selection => selection.Deserialize()); 98 | } 99 | } 100 | 101 | //---------------------------------------------------------------------- 102 | 103 | private enum NavigationType 104 | { 105 | Backward = -1, 106 | External = 0, 107 | Forward = +1, 108 | } 109 | 110 | private static NavigationType s_navigationType; 111 | 112 | private static Object[] s_oldSelection; 113 | 114 | private static readonly List s_backward = 115 | new List(); 116 | 117 | private static readonly List s_forward = 118 | new List(); 119 | 120 | private const int MaxStackCount = 128; 121 | 122 | //---------------------------------------------------------------------- 123 | 124 | private static FieldInfo GUIUtility_processEvent = 125 | typeof(GUIUtility) 126 | .GetField( 127 | "processEvent", 128 | BindingFlags.Static | 129 | BindingFlags.Public | 130 | BindingFlags.NonPublic); 131 | 132 | private static event Func processEvent 133 | { 134 | add 135 | { 136 | var processEvent = 137 | (Delegate) 138 | GUIUtility_processEvent.GetValue(null); 139 | processEvent = Delegate.Combine(processEvent, value); 140 | GUIUtility_processEvent.SetValue(null, processEvent); 141 | } 142 | remove 143 | { 144 | var processEvent = 145 | (Delegate) 146 | GUIUtility_processEvent.GetValue(null); 147 | processEvent = Delegate.Remove(processEvent, value); 148 | GUIUtility_processEvent.SetValue(null, processEvent); 149 | } 150 | } 151 | 152 | //---------------------------------------------------------------------- 153 | 154 | [InitializeOnLoadMethod] 155 | private static void InitializeOnLoad() 156 | { 157 | SerializedHistory.Load(); 158 | s_oldSelection = Selection.objects; 159 | AssemblyReloadEvents.beforeAssemblyReload += BeforeAssemblyReload; 160 | Selection.selectionChanged += OnSelectionChanged; 161 | processEvent += OnProcessEvent; 162 | } 163 | 164 | private static void BeforeAssemblyReload() 165 | { 166 | SerializedHistory.Save(); 167 | } 168 | 169 | //---------------------------------------------------------------------- 170 | 171 | private static void OnSelectionChanged() 172 | { 173 | var oldSelection = s_oldSelection; 174 | s_oldSelection = Selection.objects; 175 | 176 | if (oldSelection == null || oldSelection.Length == 0) 177 | return; 178 | 179 | var navigationType = s_navigationType; 180 | s_navigationType = NavigationType.External; 181 | switch (navigationType) 182 | { 183 | case NavigationType.External: 184 | s_forward.Clear(); 185 | s_backward.Push(oldSelection); 186 | break; 187 | case NavigationType.Forward: 188 | s_backward.Push(oldSelection); 189 | break; 190 | case NavigationType.Backward: 191 | s_forward.Push(oldSelection); 192 | break; 193 | } 194 | } 195 | 196 | //---------------------------------------------------------------------- 197 | 198 | private static bool OnProcessEvent( 199 | int instanceID, 200 | IntPtr nativeEventPtr) 201 | { 202 | HandleMouseButtonEvents(); 203 | return false; 204 | } 205 | 206 | private static void HandleMouseButtonEvents() 207 | { 208 | var currentEvent = Event.current; 209 | var currentEventType = currentEvent.type; 210 | var clickCount = currentEvent.clickCount; 211 | var isMouseUp = currentEventType == EventType.MouseUp; 212 | if (isMouseUp && clickCount == 1) 213 | { 214 | switch (currentEvent.button) 215 | { 216 | case 3: 217 | NavigateBackward(); 218 | Event.current.Use(); 219 | break; 220 | case 4: 221 | NavigateForward(); 222 | Event.current.Use(); 223 | break; 224 | } 225 | } 226 | } 227 | 228 | //---------------------------------------------------------------------- 229 | 230 | public static bool CanNavigateBackward() 231 | { 232 | return s_backward.Any(objs => objs.Any(obj => obj != null)); 233 | } 234 | 235 | public static bool CanNavigateForward() 236 | { 237 | return s_forward.Any(objs => objs.Any(obj => obj != null)); 238 | } 239 | 240 | //---------------------------------------------------------------------- 241 | 242 | [MenuItem( 243 | "Edit/Selection/Back %[", 244 | isValidateFunction: false, 245 | priority: -29)] 246 | public static void NavigateBackward() 247 | { 248 | while (CanNavigateBackward()) 249 | { 250 | var oldSelection = s_backward.Pop().RemoveNullObjects(); 251 | if (oldSelection.Length > 0) 252 | { 253 | NavigateTo(NavigationType.Backward, oldSelection); 254 | return; 255 | } 256 | } 257 | } 258 | 259 | [MenuItem( 260 | "Edit/Selection/Forward %]", 261 | isValidateFunction: false, 262 | priority: -28)] 263 | public static void NavigateForward() 264 | { 265 | while (CanNavigateForward()) 266 | { 267 | var oldSelection = s_forward.Pop().RemoveNullObjects(); 268 | if (oldSelection.Length > 0) 269 | { 270 | NavigateTo(NavigationType.Forward, oldSelection); 271 | return; 272 | } 273 | } 274 | } 275 | 276 | //---------------------------------------------------------------------- 277 | 278 | private static void NavigateTo( 279 | NavigationType navigationType, 280 | Object[] selection) 281 | { 282 | s_navigationType = navigationType; 283 | Selection.objects = selection; 284 | } 285 | 286 | //---------------------------------------------------------------------- 287 | 288 | private static void Push(this List stack, T item) 289 | { 290 | stack.Insert(0, item); 291 | for (int count = 0; (count = stack.Count) > MaxStackCount;) 292 | { 293 | stack.RemoveAt(count - 1); 294 | } 295 | } 296 | 297 | private static T Pop(this List stack) 298 | { 299 | var item = default(T); 300 | if (stack.Count > 0) 301 | { 302 | item = stack[0]; 303 | stack.RemoveAt(0); 304 | } 305 | return item; 306 | } 307 | 308 | private static Object[] RemoveNullObjects( 309 | this IEnumerable objects) 310 | { 311 | return objects.Where(obj => obj != null).ToArray(); 312 | } 313 | 314 | } 315 | 316 | } -------------------------------------------------------------------------------- /Editor/SelectionHistory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 51d1618adf06e48f49f9402210946267 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SelectionHistoryToolbarGUI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using UnityEditor; 4 | using UnityEngine; 5 | 6 | #if UNITY_2019_1_OR_NEWER 7 | using UnityEngine.UIElements; 8 | #else 9 | using UnityEngine.Experimental.UIElements; 10 | #endif // UNITY_2018_1_OR_NEWER 11 | 12 | namespace UnityExtensions 13 | { 14 | 15 | internal static class SelectionHistoryToolbarGUI 16 | { 17 | 18 | [InitializeOnLoadMethod] 19 | private static void InitializeOnLoad() 20 | { 21 | EditorApplication.delayCall += WaitForUnityEditorToolbar; 22 | } 23 | 24 | //---------------------------------------------------------------------- 25 | 26 | private static Type Toolbar = 27 | typeof(EditorGUI) 28 | .Assembly 29 | .GetType("UnityEditor.Toolbar"); 30 | 31 | private static FieldInfo Toolbar_get = 32 | Toolbar 33 | .GetField("get"); 34 | 35 | //---------------------------------------------------------------------- 36 | 37 | private static Type GUIView = 38 | typeof(EditorGUI) 39 | .Assembly 40 | .GetType("UnityEditor.GUIView"); 41 | 42 | private static PropertyInfo GUIView_imguiContainer = 43 | GUIView 44 | .GetProperty( 45 | "imguiContainer", 46 | BindingFlags.Instance | 47 | BindingFlags.Public | 48 | BindingFlags.NonPublic); 49 | 50 | //---------------------------------------------------------------------- 51 | 52 | private static FieldInfo IMGUIContainer_m_OnGUIHandler = 53 | typeof(IMGUIContainer) 54 | .GetField( 55 | "m_OnGUIHandler", 56 | BindingFlags.Instance | 57 | BindingFlags.Public | 58 | BindingFlags.NonPublic); 59 | 60 | //---------------------------------------------------------------------- 61 | 62 | private static void WaitForUnityEditorToolbar() 63 | { 64 | var toolbar = Toolbar_get.GetValue(null); 65 | if (toolbar != null) 66 | { 67 | AttachToUnityEditorToolbar(toolbar); 68 | return; 69 | } 70 | EditorApplication.delayCall += WaitForUnityEditorToolbar; 71 | } 72 | 73 | private static void AttachToUnityEditorToolbar(object toolbar) 74 | { 75 | var toolbarGUIContainer = 76 | (IMGUIContainer) 77 | GUIView_imguiContainer 78 | .GetValue(toolbar, null); 79 | 80 | var toolbarGUIHandler = 81 | (Action) 82 | IMGUIContainer_m_OnGUIHandler 83 | .GetValue(toolbarGUIContainer); 84 | 85 | toolbarGUIHandler += OnGUI; 86 | 87 | IMGUIContainer_m_OnGUIHandler 88 | .SetValue(toolbarGUIContainer, toolbarGUIHandler); 89 | } 90 | 91 | //---------------------------------------------------------------------- 92 | 93 | private class GUIResources 94 | { 95 | 96 | public const int GlyphFontSize = 26; 97 | 98 | public readonly GUIStyle 99 | commandStyle = new GUIStyle("Command"), 100 | commandLeftStyle = new GUIStyle("CommandLeft"), 101 | commandRightStyle = new GUIStyle("CommandRight"), 102 | blackBoldTextStyle = new GUIStyle(EditorStyles.boldLabel) 103 | { 104 | alignment = TextAnchor.MiddleCenter, 105 | fontSize = GlyphFontSize, 106 | }, 107 | whiteBoldTextStyle = new GUIStyle(EditorStyles.whiteBoldLabel) 108 | { 109 | alignment = TextAnchor.MiddleCenter, 110 | fontSize = GlyphFontSize, 111 | }; 112 | 113 | public const string 114 | prevTooltip = "Navigate to Previous Selection", 115 | nextTooltip = "Navigate to Next Selection"; 116 | 117 | public readonly GUIContent 118 | prevButtonContent = new GUIContent(" ", prevTooltip), 119 | nextButtonContent = new GUIContent(" ", nextTooltip); 120 | 121 | public readonly GUIContent 122 | prevGlyphContent = new GUIContent("\u2039", prevTooltip), 123 | nextGlyphContent = new GUIContent("\u203A", nextTooltip); 124 | 125 | } 126 | 127 | private static GUIResources s_gui; 128 | private static GUIResources gui 129 | { 130 | get { return s_gui ?? (s_gui = new GUIResources()); } 131 | } 132 | 133 | //---------------------------------------------------------------------- 134 | 135 | private static void OnGUI() 136 | { 137 | var prevEnabled = SelectionHistory.CanNavigateBackward(); 138 | var nextEnabled = SelectionHistory.CanNavigateForward(); 139 | 140 | 141 | #if UNITY_2019_1_OR_NEWER 142 | var guiRect = new Rect(400, 5, 32, 22); 143 | #else 144 | var guiRect = new Rect(370, 5, 32, 22); 145 | #endif // UNITY_2018_1_OR_NEWER 146 | 147 | var prevRect = guiRect; 148 | var nextRect = guiRect; 149 | nextRect.x += guiRect.width; 150 | { 151 | var prevStyle = gui.commandLeftStyle; 152 | var prevContent = gui.prevButtonContent; 153 | 154 | EditorGUI.BeginDisabledGroup(!prevEnabled); 155 | if (GUI.Button(prevRect, prevContent, prevStyle)) 156 | SelectionHistory.NavigateBackward(); 157 | EditorGUI.EndDisabledGroup(); 158 | 159 | var nextStyle = gui.commandRightStyle; 160 | var nextContent = gui.nextButtonContent; 161 | 162 | EditorGUI.BeginDisabledGroup(!nextEnabled); 163 | if (GUI.Button(nextRect, nextContent, nextStyle)) 164 | SelectionHistory.NavigateForward(); 165 | EditorGUI.EndDisabledGroup(); 166 | } 167 | 168 | var isRepaint = Event.current.type == EventType.Repaint; 169 | if (isRepaint) 170 | { 171 | var black = gui.blackBoldTextStyle; 172 | var white = gui.whiteBoldTextStyle; 173 | 174 | var no = false; 175 | var prevContent = gui.prevGlyphContent; 176 | EditorGUI.BeginDisabledGroup(!prevEnabled); 177 | // prevRect.x -= 1; 178 | prevRect.y -= 1; 179 | white.Draw(prevRect, prevContent, no, no, no, no); 180 | prevRect.y -= 1; 181 | black.Draw(prevRect, prevContent, no, no, no, no); 182 | EditorGUI.EndDisabledGroup(); 183 | // EditorGUI.DrawRect(prevRect, Color.Lerp(Color.cyan, Color.clear, 0.2f)); 184 | 185 | var nextContent = gui.nextGlyphContent; 186 | EditorGUI.BeginDisabledGroup(!nextEnabled); 187 | // nextRect.x -= 1; 188 | nextRect.y -= 1; 189 | white.Draw(nextRect, nextContent, no, no, no, no); 190 | nextRect.y -= 1; 191 | black.Draw(nextRect, nextContent, no, no, no, no); 192 | EditorGUI.EndDisabledGroup(); 193 | // EditorGUI.DrawRect(nextRect, Color.Lerp(Color.magenta, Color.clear, 0.2f)); 194 | } 195 | } 196 | 197 | } 198 | 199 | } -------------------------------------------------------------------------------- /Editor/SelectionHistoryToolbarGUI.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6732001c575bb440fabf8158c5b8bee8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/UnityExtensions.SelectionHistory.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "UnityExtensions.SelectionHistory.Editor", 3 | "references": [], 4 | "optionalUnityReferences": [], 5 | "includePlatforms": [ 6 | "Editor" 7 | ], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false 10 | } -------------------------------------------------------------------------------- /Editor/UnityExtensions.SelectionHistory.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ff717b83869f744f9a7ca46fc4f8b52b 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Garett Bass 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 58ed9af7ee3c84678bf1c8d06ebf1759 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Menu-Items.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/garettbass/UnityExtensions.SelectionHistory/11b69815f7156577d41c4d39551001aa304a8588/Menu-Items.png -------------------------------------------------------------------------------- /Menu-Items.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 95e4ac74467e64eb5884e98c497a2dc9 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 5 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | grayScaleToAlpha: 0 25 | generateCubemap: 6 26 | cubemapConvolution: 0 27 | seamlessCubemap: 0 28 | textureFormat: 1 29 | maxTextureSize: 2048 30 | textureSettings: 31 | serializedVersion: 2 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapU: -1 36 | wrapV: -1 37 | wrapW: -1 38 | nPOTScale: 1 39 | lightmap: 0 40 | compressionQuality: 50 41 | spriteMode: 0 42 | spriteExtrude: 1 43 | spriteMeshType: 1 44 | alignment: 0 45 | spritePivot: {x: 0.5, y: 0.5} 46 | spritePixelsToUnits: 100 47 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 48 | spriteGenerateFallbackPhysicsShape: 1 49 | alphaUsage: 1 50 | alphaIsTransparency: 0 51 | spriteTessellationDetail: -1 52 | textureType: 0 53 | textureShape: 1 54 | singleChannelComponent: 0 55 | maxTextureSizeSet: 0 56 | compressionQualitySet: 0 57 | textureFormatSet: 0 58 | platformSettings: 59 | - serializedVersion: 2 60 | buildTarget: DefaultTexturePlatform 61 | maxTextureSize: 2048 62 | resizeAlgorithm: 0 63 | textureFormat: -1 64 | textureCompression: 1 65 | compressionQuality: 50 66 | crunchedCompression: 0 67 | allowsAlphaSplitting: 0 68 | overridden: 0 69 | androidETC2FallbackOverride: 0 70 | spriteSheet: 71 | serializedVersion: 2 72 | sprites: [] 73 | outline: [] 74 | physicsShape: [] 75 | bones: [] 76 | spriteID: 77 | vertices: [] 78 | indices: 79 | edges: [] 80 | weights: [] 81 | spritePackingTag: 82 | userData: 83 | assetBundleName: 84 | assetBundleVariant: 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityExtensions.SelectionHistory 2 | 3 | Adds menu items to navigate back and forward in the Unity Editor, and handy back/forward buttons to the toolbar. Mouse buttons 3 & 4 are mapped to back and forward respectively. 4 | 5 | ![Menu Items](Menu-Items.png) 6 | 7 | ## Installation 8 | 9 | Just clone this repo somewhere inside your Unity project's `Assets` folder. 10 | 11 | ```sh 12 | $ cd Assets 13 | $ git clone https://github.com/garettbass/UnityExtensions.SelectionHistory 14 | ``` 15 | 16 | ## API 17 | 18 | Your code can invoke these methods if you want to programmatically navigate backward or forward through the selection history: 19 | 20 | ```cs 21 | UnityExtensions.SelectionHistory.CanNavigateBackward(); 22 | UnityExtensions.SelectionHistory.NavigateBackward(); 23 | 24 | UnityExtensions.SelectionHistory.CanNavigateForward(); 25 | UnityExtensions.SelectionHistory.NavigateForward(); 26 | ``` -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4cdae05a18338498b94255a58c6edffd 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.unityextensions.selectionhistory", 3 | "displayName": "UnityExtensions.SelectionHistory", 4 | "version": "1.0.0", 5 | "unity": "2018.1", 6 | "description": "Navigate the Unity editor with browser-style back/forward buttons, keyboard shortcuts, and mouse button support.", 7 | "keywords": [ 8 | "selection", 9 | "history", 10 | "navigation" 11 | ], 12 | "category": "Unity" 13 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8476c246e4fb942eea188cec0df283c7 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------