Unity编辑器扩展--Scene Manager

我的Github:https://github.com/LanslotChung/Unity3d-Editor-Extensions

专门在Github上记录我写的一些编辑器扩展工具,这是Scene Manager的源码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Linq;
using System.IO;
using UnityEditor.SceneManagement;
using UnityEditorInternal;

public class SceneManager : EditorWindow {
    #region MenuItem
    [MenuItem("Tools/Scene Manager %M")]
    static void ShowWindow()
    {
        var sceneFinder = EditorWindow.GetWindow<SceneManager>();
        sceneFinder.titleContent = new GUIContent("Scene Manager");
        sceneFinder.Show();
    }
    #endregion
    
    private List<SceneInfo> scenesInProject = new List<SceneInfo>();
    private List<SceneInfo> scenesInSettings = new List<SceneInfo>();
    private ReorderableList projectList;
    private ReorderableList settingList;
    private Vector2 projectScrollPosition;
    private Vector2 settingScrollPosition;
    void OnGUI(){
        if(projectList == null){
            projectList = new ReorderableList(scenesInProject,typeof(SceneInfo),false,false,false,false);
            projectList.drawHeaderCallback =
            (Rect rect) => {  
                EditorGUI.LabelField(rect, "Scenes In Project",EditorStyles.boldLabel);
            };
            projectList.drawElementCallback =
            (Rect rect, int index, bool isActive, bool isFocused) =>{
                var sceneInfo = scenesInProject[index];
                EditorGUI.LabelField(new Rect(rect.x,rect.y,rect.width - 60,rect.height),sceneInfo.name);
                if(GUI.Button(new Rect(rect.width - 60,rect.y,20,rect.height),"P",GUIStyle.none)){
                    EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath<SceneAsset>(sceneInfo.path));
                }
                if(GUI.Button(new Rect(rect.width - 40,rect.y,20,rect.height),"O",GUIStyle.none)){
                    EditorSceneManager.OpenScene(sceneInfo.path);
                }
                if(GUI.Button(new Rect(rect.width - 20,rect.y,20,rect.height),"A",GUIStyle.none)){
                    var tmpSceneIn = EditorBuildSettings.scenes.ToList();
                    tmpSceneIn.Add(new EditorBuildSettingsScene(sceneInfo.path, true));
                    EditorBuildSettings.scenes = tmpSceneIn.ToArray();
                    AssetDatabase.Refresh();
                }
            };
        }
        if(settingList == null){
            settingList = new ReorderableList(scenesInSettings,typeof(SceneInfo),true,false,false,false);
            settingList.onReorderCallback = 
            (ReorderableList list) =>{
                EditorBuildSettings.scenes = 
                    list.list.Cast<SceneInfo>()
                    .Select(scene => {
                        var editorScene = new EditorBuildSettingsScene();
                        editorScene.enabled = scene.enabledInSettings;
                        editorScene.path = scene.path;
                        return editorScene;
                    })
                    .ToArray();
            };
            settingList.drawHeaderCallback =
            (Rect rect) => {  
                EditorGUI.LabelField(rect, "Scenes In Setting",EditorStyles.boldLabel);
            };
            settingList.drawElementCallback =
            (Rect rect, int index, bool isActive, bool isFocused) =>{
                var sceneInfo = scenesInSettings[index];
                sceneInfo.enabledInSettings = GUI.Toggle(new Rect(rect.x,rect.y,14,rect.height),sceneInfo.enabledInSettings,string.Empty);
                var tmpScenesInSetting = EditorBuildSettings.scenes.ToList();
                tmpScenesInSetting.Where(scene => scene.path == sceneInfo.path).First().enabled = sceneInfo.enabledInSettings;
                EditorGUI.LabelField(new Rect(rect.x + 14,rect.y,rect.width - 34,rect.height),sceneInfo.name);
                EditorGUI.LabelField(new Rect(rect.width - 8,rect.y,20,rect.height),index.ToString());
            };
        }
        scenesInProject = GetScenesInProject();
        scenesInSettings = GetScenesInSettings();
        
        projectList.list = scenesInProject;
        settingList.list = scenesInSettings;
        
        settingScrollPosition = EditorGUILayout.BeginScrollView(settingScrollPosition);
        settingList.DoLayoutList();
        EditorGUILayout.EndScrollView();
        
        projectScrollPosition = EditorGUILayout.BeginScrollView(projectScrollPosition);
        projectList.DoLayoutList();
        EditorGUILayout.EndScrollView();
    }
    
    #region SceneInfo
    private class SceneInfo{
        public bool enabledInSettings;
        public string name;
        public string path;
    }
    #endregion
    #region Util
    private List<SceneInfo> GetScenesInSettings(){
        List<SceneInfo> scenes = 
            EditorBuildSettings.scenes
            .Select(scene =>{
                var sceneInfo = new SceneInfo();
                sceneInfo.enabledInSettings = scene.enabled;
                sceneInfo.path = scene.path;
                sceneInfo.name = Path.GetFileNameWithoutExtension(sceneInfo.path);
                return sceneInfo;
            })
            .ToList();
        //重名的Scene应该显示路径,避免混淆
        scenes.GroupBy(scene => scene.name)
            .Where(group => group.Count() > 1)
            .SelectMany(group => group.ToList())
            .ToList()
            .ForEach(scene => scene.name = scene.path.Substring(7).Replace(".unity", ""));
        return scenes;
    }
    private List<SceneInfo> GetScenesInProject(){
        List<SceneInfo> scenes = AssetDatabase.FindAssets("t:Scene")
            .Select(id =>
            {
                var info = new SceneInfo();
                info.path = AssetDatabase.GUIDToAssetPath(id);
                info.name = Path.GetFileNameWithoutExtension(info.path);
                info.enabledInSettings =
                    EditorBuildSettings.scenes
                    .Where(scene => scene.enabled)
                    .Select(scene => scene.path)
                    .Contains(info.path);
                return info;
            })
            .ToList();
        //重名的Scene应该显示路径,避免混淆
        scenes.GroupBy(scene => scene.name)
            .Where(group => group.Count() > 1)
            .SelectMany(group => group.ToList())
            .ToList()
            .ForEach(scene => scene.name = scene.path.Substring(7).Replace(".unity", ""));
        return scenes;
    }
    #endregion
}
原文地址:https://www.cnblogs.com/CodeSnippet/p/8038792.html