我们在Unity游戏开发过程中,可能会有许许多多的场景,就比如我们的启动场景是在Scene目录下,而一些游戏场景却在其他目录下,比如场景目录等等。
当然当我们做好场景管理和目录管理时,这种需要不停的关键字搜索场景名然后打开场景的操作可能不太需要。但是有时候目录管理并不可能那么如愿。又或者说我们只是想修改一个预制体,然后再去切场景,还是需要去找到想要打开的场景等比较麻烦的步骤。
所以为了开发的方便,我做了一个快速切换场景的窗口小工具,只需要将常用的场景拖到窗口中,以后就可以只需要点击一下就可以快速切换,无需多余的搜索。
话不多说,直接上代码了,代码里做了一些注释,其实都是很简单的逻辑,可能有一些API比较陌生,大家查一查也就都懂了。
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
public class CustomSceneSwitcherWindow : EditorWindow
{
private static EditorWindow customSceneSwitcherWindow;
private List<string> customScenes = new List<string>();
private Vector2 scrollPos;
private const string CustomScenesKey = "CustomSceneSwitcherWindow.CustomScenes";
private List<int> scenesToRemove = new List<int>();
[MenuItem("Tools/快速切换场景工具")]
public static void ShowWindow()
{
customSceneSwitcherWindow = GetWindow<CustomSceneSwitcherWindow>("快速切换场景工具");
}
private void OnEnable()
{
LoadCustomScenes();
}
private void OnDisable()
{
SaveCustomScenes();
}
private void OnGUI()
{
HandleDragAndDrop();
GUILayout.Label("场景列表", EditorStyles.boldLabel);
// 创建一个scrollview的滑动框
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
for (int i = 0; i < customScenes.Count; i++)
{
// 这段代码只是为了想一排放两个场景按钮,不需要的可以删除,可自行修改
if (i % 2 == 0)
{
GUILayout.BeginHorizontal();
}
string scenePath = customScenes[i];
string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath);
if (GUILayout.Button(sceneName, GUILayout.Width(125), GUILayout.Height(30)))
{
// 左键直接打开场景
if (Event.current.button == 0)
{
// 点击打开场景
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
{
EditorSceneManager.OpenScene(scenePath);
}
}
// 右键可以跳转到文件并选择
else if (Event.current.button == 1)
{
Debug.Log("选中的场景路径为:" + scenePath);
// 使用EditorGUIUtility选中资源
EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath<Object> (scenePath));
}
}
// 每个场景按钮后加一个删除按钮
if (GUILayout.Button("×", GUILayout.Width(30), GUILayout.Height(30)))
{
scenesToRemove.Add(i);
}
// 这段代码只是为了想一排放两个场景按钮,不需要的可以删除,可自行修改
if (i % 2 == 1 || i == customScenes.Count - 1)
{
GUILayout.EndHorizontal();
}
}
EditorGUILayout.EndScrollView();
GUILayout.Space(10);
if (GUILayout.Button("一键清理列表", GUILayout.Height(30)))
{
customScenes.Clear();
SaveCustomScenes();
}
// 处理布局后执行删除防止报错
if (scenesToRemove.Count > 0)
{
scenesToRemove.Sort();
scenesToRemove.Reverse();
foreach (var index in scenesToRemove)
{
customScenes.RemoveAt(index);
}
scenesToRemove.Clear();
SaveCustomScenes();
}
}
// 将整个窗体作为可拖拽的区域
private void HandleDragAndDrop()
{
Event evt = Event.current;
switch (evt.type)
{
case EventType.DragUpdated:
case EventType.DragPerform:
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
if (evt.type == EventType.DragPerform)
{
DragAndDrop.AcceptDrag();
foreach (Object draggedObject in DragAndDrop.objectReferences)
{
if (draggedObject is SceneAsset)
{
string path = AssetDatabase.GetAssetPath(draggedObject);
if (!customScenes.Contains(path))
{
customScenes.Add(path);
}
}
}
// 保存
SaveCustomScenes();
}
evt.Use();
break;
}
}
// 加载在本地保存的路径
private void LoadCustomScenes()
{
customScenes.Clear();
int sceneCount = EditorPrefs.GetInt(CustomScenesKey + ".Count", 0);
for (int i = 0; i < sceneCount; i++)
{
string scenePath = EditorPrefs.GetString(CustomScenesKey + "." + i, string.Empty);
if (!string.IsNullOrEmpty(scenePath))
{
customScenes.Add(scenePath);
}
}
}
// 在本地保存场景路径
private void SaveCustomScenes()
{
EditorPrefs.SetInt(CustomScenesKey + ".Count", customScenes.Count);
for (int i = 0; i < customScenes.Count; i++)
{
EditorPrefs.SetString(CustomScenesKey + "." + i, customScenes[i]);
}
}
}
使用方法也很简单,Tool->快速切换场景工具,在这个标题栏下打开工具即可。然后直接将场景拖到工具窗口即可。