在大型项目中经常遇到新旧模型替换的问题,如果没有一个好的替换习惯很容易造成模型Mesh丢失的情况。unity在切换场景的时候会因为模型丢失报错。
例如:
NullReferenceException: Object reference not set to an instance of an object
UnityEngine.InternalStaticBatchingUtility.CombineGameObjects (UnityEngine.GameObject[] gos, UnityEngine.GameObject staticBatchRoot, System.Boolean isEditorPostprocessScene, UnityEngine.InternalStaticBatchingUtility+StaticBatcherGOSorter sorter) (at <2e0a48134cc845028fb11656fdc79d23>:0)
UnityEngine.InternalStaticBatchingUtility.Combine (UnityEngine.GameObject staticBatchRoot, System.Boolean combineOnlyStatic, System.Boolean isEditorPostprocessScene, UnityEngine.InternalStaticBatchingUtility+StaticBatcherGOSorter sorter) (at <2e0a48134cc845028fb11656fdc79d23>:0)
UnityEditor.UnityBuildPostprocessor.OnProcessScene (UnityEngine.SceneManagement.Scene scene, UnityEditor.Build.Reporting.BuildReport report) (at <23d96447c030422fb76b5c08cdcf57cc>:0)
UnityEditor.Build.BuildPipelineInterfaces+<>c__DisplayClass16_0.<OnSceneProcess>b__1 (UnityEditor.Build.IProcessSceneWithReport spp) (at <23d96447c030422fb76b5c08cdcf57cc>:0)
UnityEditor.Build.BuildPipelineInterfaces.InvokeCallbackInterfacesPair[T1,T2] (System.Collections.Generic.List`1[T] oneInterfaces, System.Action`1[T] invocationOne, System.Collections.Generic.List`1[T] twoInterfaces, System.Action`1[T] invocationTwo, System.Boolean exitOnFailure) (at <23d96447c030422fb76b5c08cdcf57cc>:0)
UnityEditor.Build.BuildPipelineInterfaces:OnSceneProcess(Scene, BuildReport)
虽然这种错误不是致命的,但是作为程序开发者不应该允许程序有报错而不解决,通过以下脚本可以简易检测模型Mesh是否丢失。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CheckMesh : MonoBehaviour
{
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
Check();
}
void Check()
{
GameObject[] all = Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[];
for (int i = 0; i < all.Length; i++)
{
var item = all[i];
if (item.scene.isLoaded && item.activeInHierarchy && item.GetComponent<MeshFilter>()!=null)
{
var mesh = item.GetComponent<MeshFilter>().sharedMesh;
if (mesh == null || mesh.vertexCount <= 0)
{
print(GetTransPath(item.transform));
}
}
}
}
/// <summary>
/// 获得GameObject在Hierarchy中的完整路径
/// </summary>
public static string GetTransPath(Transform trans)
{
if (!trans.parent)
{
return trans.name;
}
return GetTransPath(trans.parent) + "/" + trans.name;
}
}
具体用法为:
将此脚本挂到场景任意激活物体上运行即可,场景加载完成后按空格键
就会打印Mesh丢失模型的具体路径。