Unity编辑器中如何扩展场景创建功能,实现后续流程自动化?
Unity扩展场景创建自动化流程方案
完全可行,Unity的Editor扩展机制可以完美实现你要的功能——直接扩展右键菜单、弹出配置对话框,一键完成场景创建+Addressable配置+ScriptableObject关联全流程。下面是具体实现思路和代码示例:
核心实现步骤
1. 扩展Project视图右键菜单
用UnityEditor的MenuItem特性,在Assets/Create菜单下添加自定义选项,设置优先级让它挨着默认Scene选项显示:
using UnityEngine; using UnityEditor; using System.IO; public class CustomSceneCreator { // 优先级设为101(默认Scene是100),让选项排在默认Scene下方 [MenuItem("Assets/Create/自动化场景", false, 101)] public static void ShowCustomSceneDialog() { // 获取右键点击的目标文件夹路径 string targetFolder = "Assets"; if (Selection.activeObject != null) { targetFolder = AssetDatabase.GetAssetPath(Selection.activeObject); // 如果选中的是文件,取它所在的文件夹 if (!Directory.Exists(targetFolder)) { targetFolder = Path.GetDirectoryName(targetFolder); } } // 弹出配置窗口 CustomSceneConfigWindow.ShowWindow(targetFolder); } }
2. 制作配置对话框
用EditorWindow做一个轻量弹窗,让用户输入场景名、勾选需要的自动化操作:
using UnityEditor; using UnityEngine; public class CustomSceneConfigWindow : EditorWindow { private string sceneName = "NewScene"; private bool makeAddressable = true; private bool addToSceneListSO = true; private string targetFolder; public static void ShowWindow(string folder) { var window = GetWindow<CustomSceneConfigWindow>("场景配置"); window.targetFolder = folder; window.minSize = new Vector2(300, 150); } private void OnGUI() { GUILayout.Label("场景创建配置", EditorStyles.boldLabel); sceneName = EditorGUILayout.TextField("场景名称", sceneName); makeAddressable = EditorGUILayout.Toggle("设为Addressable", makeAddressable); addToSceneListSO = EditorGUILayout.Toggle("添加到场景列表SO", addToSceneListSO); if (GUILayout.Button("创建并配置")) { CreateAndConfigureScene(); Close(); } } private void CreateAndConfigureScene() { SceneCreationUtils.CreateScene(targetFolder, sceneName, makeAddressable, addToSceneListSO); } }
3. 实现自动化配置逻辑
封装一个工具类,处理场景创建、Addressable配置、ScriptableObject关联的具体逻辑:
using UnityEditor; using UnityEngine; using UnityEditor.AddressableAssets; using UnityEditor.AddressableAssets.Settings; using System.IO; using System.Collections.Generic; public static class SceneCreationUtils { public static void CreateScene(string targetFolder, string sceneName, bool makeAddressable, bool addToSO) { // 1. 创建并保存场景 string scenePath = Path.Combine(targetFolder, $"{sceneName}.unity"); var newScene = UnityEditor.SceneManagement.EditorSceneManager.NewScene( UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects, UnityEditor.SceneManagement.NewSceneMode.Single ); UnityEditor.SceneManagement.EditorSceneManager.SaveScene(newScene, scenePath); AssetDatabase.Refresh(); // 2. 配置Addressable if (makeAddressable) { var addressableSettings = AddressableAssetSettingsDefaultObject.Settings; if (addressableSettings == null) { Debug.LogError("未初始化Addressable设置,请先开启Addressable系统"); return; } // 获取默认组(可按需修改为指定分组) var defaultGroup = addressableSettings.DefaultGroup; var sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(scenePath); // 添加到Addressable并设置标识 var entry = addressableSettings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(scenePath), defaultGroup); entry.address = sceneName; entry.labels.Add("Scene"); AddressableAssetSettings.Save(addressableSettings); } // 3. 添加到ScriptableObject if (addToSO) { // 替换为你自己的场景列表SO路径 var sceneListSO = AssetDatabase.LoadAssetAtPath<SceneListSO>("Assets/Resources/SceneListSO.asset"); if (sceneListSO != null) { var sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(scenePath); sceneListSO.scenes.Add(sceneAsset); EditorUtility.SetDirty(sceneListSO); AssetDatabase.SaveAssets(); } else { Debug.LogError("未找到SceneListSO,请确认路径正确"); } } Debug.Log($"场景 {sceneName} 已创建并完成配置"); } } // 示例场景列表ScriptableObject(按需修改字段) [CreateAssetMenu(fileName = "SceneListSO", menuName = "ScriptableObjects/场景列表")] public class SceneListSO : ScriptableObject { public List<SceneAsset> scenes = new List<SceneAsset>(); }
注意事项
- 确保已导入Addressable包,否则
UnityEditor.AddressableAssets命名空间会报错 - 提前创建好你的场景列表ScriptableObject,并修改代码中的对应路径
- 所有代码需放在
Editor文件夹下,避免打包时出现编译错误 - 可根据需求扩展对话框选项,比如让用户选择Addressable分组、自定义标签等
内容的提问来源于stack exchange,提问作者Giedrius Želvys
相关产品推荐
相关产品推荐

