Unity打包游戏时出现“SceneAsset类型或命名空间未找到”错误求助
解决Unity打包时SceneAsset找不到的问题
这不是Unity的Bug,是你对SceneAsset的使用场景理解有误:
SceneAsset属于UnityEditor命名空间,这个命名空间下的所有类型和代码仅在Unity编辑器环境中有效。游戏打包时,Unity会自动剔除所有Editor相关代码,所以打包阶段会出现“找不到SceneAsset类型”的报错。
下面提供两种实用的解决方案:
方案1:改用Unity内置Scene引用(推荐,适用于2019.3+版本)
Unity 2019.3及以上版本支持直接在Inspector中拖拽场景到Scene类型字段,无需依赖Editor专属的SceneAsset。修改代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class ProvincePinScript : MonoBehaviour { public int ActiveWorldProvinceID; public Scene[] WorldProvinces; // 替换为Scene类型 public void Begin() { Invoke("Travel", 4f); } public void Travel() { SceneManager.LoadScene(WorldProvinces[ActiveWorldProvinceID].name); } }
⚠️ 注意:务必将所有需要加载的场景添加到Build Settings → Scenes In Build列表中,否则打包后无法正常加载。
方案2:分离Editor与Runtime代码(适用于老版本Unity)
如果你的Unity版本不支持直接引用Scene类型,可以通过“编辑器辅助赋值+Runtime存储场景名”的方式解决,核心是把Editor相关代码隔离在Editor文件夹(打包时不会被包含):
1. Runtime脚本(放在普通文件夹,不要在Editor目录下)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class ProvincePinScript : MonoBehaviour { public int ActiveWorldProvinceID; public string[] WorldProvinceNames; // 存储场景名字符串 public void Begin() { Invoke("Travel", 4f); } public void Travel() { SceneManager.LoadScene(WorldProvinceNames[ActiveWorldProvinceID]); } }
2. Editor辅助脚本(必须放在Editor文件夹下)
using UnityEditor; using UnityEngine; using System.Collections.Generic; [CustomEditor(typeof(ProvincePinScript))] public class ProvincePinEditor : Editor { private SerializedProperty _provinceNames; private void OnEnable() { _provinceNames = serializedObject.FindProperty("WorldProvinceNames"); } public override void OnInspectorGUI() { var targetScript = (ProvincePinScript)target; // 临时存储SceneAsset,方便在Inspector拖拽赋值 var sceneAssets = new List<SceneAsset>(); for (int i = 0; i < _provinceNames.arraySize; i++) { var sceneName = _provinceNames.GetArrayElementAtIndex(i).stringValue; var scenePath = SceneUtility.GetScenePathByBuildIndex(SceneManager.GetSceneByName(sceneName).buildIndex); sceneAssets.Add(AssetDatabase.LoadAssetAtPath<SceneAsset>(scenePath)); } // 显示拖拽界面 var newScenes = EditorGUILayout.ObjectField("World Provinces", sceneAssets.ToArray(), typeof(SceneAsset), false) as SceneAsset[]; // 将拖拽的SceneAsset转换为场景名,同步到Runtime字段 if (newScenes != null) { _provinceNames.arraySize = newScenes.Length; for (int i = 0; i < newScenes.Length; i++) { if (newScenes[i] == null) continue; var scenePath = AssetDatabase.GetAssetPath(newScenes[i]); _provinceNames.GetArrayElementAtIndex(i).stringValue = System.IO.Path.GetFileNameWithoutExtension(scenePath); } } serializedObject.ApplyModifiedProperties(); // 显示其他默认字段 DrawDefaultInspector(); } }
这种方式既保留了编辑器里拖拽场景的便捷性,又避免了打包时的Editor代码冲突。
内容的提问来源于stack exchange,提问作者MariiiBanann
相关产品推荐
相关产品推荐

