美术制作场景的时候习惯放置一些参照物,由于每次他们都会忘记删除,所以我们制作了一个脚本根据源场景自动生成一份新场景,以节点命名,生成的时候自动删除这些参照物。如下图所示,场景烘焙过,只保留Scene节点,导出新场景其他节点都删除掉。

如下图所示,拷贝场景后只保留了Scene节点,其他都删除了。

然后看下引用,新生成场景明明是空的为啥会引用已经删除掉的资源呢?这样在打Assetbundle的时候就会打入额外不需要的资源了。
原因就是LightingData的锅,需要将新场景拖入LightData才行。
每次手动当然不行,一定要自动。用文本打开以下LightingData,发现里面都是二进制,如何改呢?我是一点点试验的,发现可以用SerializedObject来改,如下代码所示,拷贝场景、删除节点、替换LightData里的场景自动完成。
[MenuItem("1/复制场景")]
static void CopyScene()
{
EditorSceneManager.MarkAllScenesDirty();
EditorSceneManager.SaveOpenScenes();
var goArray = EditorSceneManager.GetActiveScene().GetRootGameObjects();
foreach (var go in goArray)
{
if (go.name != "Scene")
{
Object.DestroyImmediate(go);
}
}
EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene(), "Assets/Copy.unity", true);
var Scene = EditorSceneManager.OpenScene("Assets/Copy.unity");
LightingDataAsset asset = GameObject.Instantiate(Lightmapping.lightingDataAsset);
SerializedObject obj = new SerializedObject(asset);
SerializedProperty property = obj.FindProperty("m_Scene");
SceneAsset assetscene = AssetDatabase.LoadAssetAtPath<SceneAsset>(Scene.path); //替换新场景
property.objectReferenceValue = assetscene;
obj.ApplyModifiedProperties();
string lightDataPath = AssetDatabase.GetAssetPath(Lightmapping.lightingDataAsset);
AssetDatabase.CreateAsset(asset, lightDataPath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
这样在打场景Assetbundle才能是最小化的。
- 本文固定链接: https://www.xuanyusong.com/archives/4935
- 转载请注明: 雨松MOMO于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!



有源码的话看下就会发现,确实只序列化了m_Scene这个字段,所以其他的都无法反序列化出来(2021.3版本)
对于整体场景使用简单参照物或者2D场景的话,使用ProjectSetting ->Editor ->EdittingEnviroument 更方便,配置一个单独的环境场景,在prefab模式下会叠加一个无法编辑的背景场景
完全看不明白,能讲得通俗易懂点么!!
m_Scene以下的字段,FindProperty找不到。。。
得到SceneAsset 也可以反射获取数据了
我记得Debug模式的Ispector面板上看到的东西就是SerializedObject可视化的结果。所以在那里看到的所有结构都可以通过SerialiedObject获取到。曾经用它来处理过Shader变体统计
可以这样说,但是变量名和Inspector面板上的可能不一样。对于这个例子,lightingdata.asset文件里是二进制保存的, 我是使用assetstudio解开发现里面序列化了m_Scene变量,随后尝试替换发现确实解决问题了