My Shortcuts - A Universal Asset Shortcut Panel for Unity Editor
Working on a large Unity project often means navigating through countless folders just to find the same scenes, prefabs, scripts, materials, or other assets over and over again. Although it may seem like a small task, it quickly becomes repetitive and interrupts your workflow.
My Shortcuts is a lightweight Unity Editor extension that lets you create quick-access shortcuts to your most frequently used assets directly inside the Unity Editor.
Features
Universal Asset Shortcuts
Unlike tools that only support scenes or prefabs, My Shortcuts works with virtually any asset stored in your Unity project, including:
- Scenes (.unity)
- Prefabs
- C# Scripts
- Materials
- Textures
- Sprites
- Audio Clips
- Animations
- Scriptable Objects
- Folders
- Any other asset available in the Project Window
Simply drag and drop an asset into the panel to create a shortcut.
Easy Drag & Drop
Adding shortcuts couldn't be easier.
- Open Window → My Shortcuts
- Drag any asset from the Project Window.
- Drop it into the Drop Assets Here area.
That's it—no additional setup required.
Double-Click to Open Assets
Every shortcut can be opened with a simple double-click.
The behavior automatically adapts to the asset type:
- Scenes are opened using Unity's Scene Manager, displaying the standard Save Modified Scene dialog if necessary.
- Folders are selected and highlighted in the Project Window.
- Prefabs open directly in Prefab Mode.
- Scripts are launched in your default IDE (Visual Studio, Rider, VS Code, etc.).
- All other assets are opened using Unity's built-in asset handling.
Native Unity Icons
Each shortcut displays Unity's original asset icon, making it easy to identify different asset types at a glance.
Whether it's a prefab, material, folder, scene, texture, script, or audio file, the correct icon is displayed automatically.
GUID-Based Storage
Instead of storing file paths, My Shortcuts stores Unity asset GUIDs.
This approach provides several advantages:
- Shortcuts continue to work even after assets are moved.
- Renaming assets does not break existing shortcuts.
- More reliable for long-term projects.
Automatically Saved
All shortcuts are stored using EditorPrefs, so your favorites remain available even after:
- Closing Unity
- Reopening the project
- Restarting your computer
No need to recreate your shortcut list every time you work.
Remove Shortcuts Easily
Each shortcut includes a small × button for quick removal.
Removing a shortcut only deletes it from the panel—it never deletes the actual asset.
Why Use My Shortcuts?
This tool is especially useful for medium and large Unity projects where frequently used assets are scattered across multiple folders.
Common use cases include:
- Main Menu Scene
- Gameplay Scene
- Player Prefab
- UI Prefabs
- Frequently edited Materials
- Core Scripts
- Favorite Asset Folders
- Audio Clips
- Animations
- Scriptable Objects
Instead of constantly searching through the Project Window, everything important is only two clicks away.
Perfect For
My Shortcuts is ideal for:
- Game Developers
- Unity Programmers
- Technical Artists
- Level Designers
- UI Designers
- Solo Developers
- Unity Development Teams
Anyone looking to speed up their Unity workflow will benefit from this tool.
Conclusion
My Shortcuts is a simple yet powerful Unity Editor extension designed to improve productivity by giving you instant access to your most important assets. With drag-and-drop support, GUID-based persistence, automatic asset handling, and native Unity icons, it helps reduce time spent searching for files so you can focus on building your game.
How to use it: Make a script named "MyShortcutsWindow.cs" and paste this code:
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.SceneManagement;
/// <summary>
/// Custom dockable panel untuk shortcut segala jenis asset di Project Window.
/// Drag asset apa saja (Scene, Folder, Prefab, Material, dll.) ke panel ini.
/// Double-click shortcut untuk membuka atau highlight asset tersebut.
/// </summary>
public class MyShortcutsWindow : EditorWindow
{
private List<string> shortcutGUIDs = new List<string>();
private Vector2 scrollPosition;
private const string PrefsKey = "MyShortcuts_ShortcutGUIDs";
[MenuItem("Window/My Shortcuts")]
public static void ShowWindow()
{
var window = GetWindow<MyShortcutsWindow>("My Shortcuts");
window.minSize = new Vector2(200, 100);
}
private void OnEnable() => LoadShortcuts();
private void OnDisable() => SaveShortcuts();
private void LoadShortcuts()
{
string saved = EditorPrefs.GetString(PrefsKey, "");
if (!string.IsNullOrEmpty(saved))
shortcutGUIDs = saved.Split('|').Where(s => !string.IsNullOrEmpty(s)).ToList();
}
private void SaveShortcuts() =>
EditorPrefs.SetString(PrefsKey, string.Join("|", shortcutGUIDs));
private void OnGUI()
{
EditorGUILayout.LabelField("My Shortcuts", EditorStyles.boldLabel);
EditorGUILayout.HelpBox("Drag any assets, scenes, or folders here to create shortcuts", MessageType.Info);
// Drop area
Rect dropAreaRect = EditorGUILayout.GetControlRect(GUILayout.Height(40), GUILayout.ExpandWidth(true));
GUI.Box(dropAreaRect, "Drop Assets Here");
HandleDropArea(dropAreaRect);
EditorGUILayout.Space();
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
if (shortcutGUIDs.Count == 0)
EditorGUILayout.HelpBox("No shortcuts yet. Drag assets to the drop area above.", MessageType.Info);
else
{
// Menggunakan for-loop terbalik agar aman saat menghapus item di tengah iterasi
for (int i = shortcutGUIDs.Count - 1; i >= 0; i--)
{
DrawShortcutItem(i);
}
}
EditorGUILayout.EndScrollView();
}
private void HandleDropArea(Rect dropArea)
{
Event e = Event.current;
if (dropArea.Contains(e.mousePosition))
{
if (e.type == EventType.DragUpdated)
{
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
e.Use();
}
else if (e.type == EventType.DragPerform)
{
DragAndDrop.AcceptDrag();
bool addedAny = false;
foreach (var draggedObject in DragAndDrop.objectReferences)
{
if (AddShortcut(draggedObject)) addedAny = true;
}
if (!addedAny)
Debug.LogWarning("My Shortcuts: Failed to add shortcut (invalid asset or already exists).");
e.Use();
}
}
}
private bool AddShortcut(UnityEngine.Object obj)
{
string path = AssetDatabase.GetAssetPath(obj);
if (string.IsNullOrEmpty(path)) return false;
// DIUBAH: Validasi diperlonggar agar menerima semua file yang ada di Project (Asset Database)
string guid = AssetDatabase.AssetPathToGUID(path);
if (string.IsNullOrEmpty(guid) || shortcutGUIDs.Contains(guid))
return false;
shortcutGUIDs.Add(guid);
return true;
}
private void DrawShortcutItem(int index)
{
string guid = shortcutGUIDs[index];
string path = AssetDatabase.GUIDToAssetPath(guid);
var obj = AssetDatabase.LoadMainAssetAtPath(path);
if (obj == null)
{
shortcutGUIDs.RemoveAt(index);
return;
}
// Membuat area klik untuk baris shortcut ini
Rect itemRect = EditorGUILayout.BeginHorizontal(GUILayout.Height(20));
// Render icon bawaan dari asset (Prefab, Material, Script dll otomatis menyesuaikan)
GUILayout.Label(AssetDatabase.GetCachedIcon(path), GUILayout.Width(16), GUILayout.Height(16));
EditorGUILayout.LabelField(obj.name);
if (GUILayout.Button("×", GUILayout.Width(20), GUILayout.Height(16)))
{
shortcutGUIDs.RemoveAt(index);
EditorGUILayout.EndHorizontal();
return;
}
EditorGUILayout.EndHorizontal();
// Handle Event Double Click
if (Event.current.type == EventType.MouseDown && itemRect.Contains(Event.current.mousePosition) && Event.current.clickCount == 2)
{
OpenShortcut(obj, path);
Event.current.Use();
}
}
private void OpenShortcut(UnityEngine.Object obj, string path)
{
// 1. Jika tipenya folder, lakukan cara lama (Fokus & Ping)
if (AssetDatabase.IsValidFolder(path))
{
EditorUtility.FocusProjectWindow();
Selection.activeObject = obj;
EditorGUIUtility.PingObject(obj);
}
// 2. Jika tipenya Scene (.unity), gunakan SceneManager agar ada prompt "Save Scene" jika scene saat ini berubah
else if (path.EndsWith(".unity"))
{
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
EditorSceneManager.OpenScene(path);
}
// 3. Untuk segala jenis file lainnya (Prefab, Script, Audio, Material, dll.)
else
{
// Selalu jalankan Ping & Select agar user tahu letak file aslinya
EditorUtility.FocusProjectWindow();
Selection.activeObject = obj;
EditorGUIUtility.PingObject(obj);
// Buka asset secara universal (Masuk Prefab Mode, buka IDE script, dll.)
AssetDatabase.OpenAsset(obj);
}
}
}

Comments
Post a Comment