Unity - 查找当前场景中的Missing组件

最近遇到一个问题是从别的工程中拷贝的一个Prefab文件在保存的时候报NullRefrence的引用错误,经查找后确定是Prefab中存在丢失的脚本或者组件中丢失引用或者存在None的引用,如下几种:


None Refrences
Missing Scripts


Missing Components

手动找总会漏掉,然后还是报错,所以想到用脚本工具来查找,核心部分是判断脚本的引用存在但是引用值丢失了,如下:

                    if(sp.propertyType == SerializedPropertyType.ObjectReference)

                    {

                        if(sp.objectReferenceValue == null   && sp.objectReferenceInstanceIDValue != 0)

                        {

                            ShowError(context, go, c.GetType().Name, ObjectNames.NicifyVariableName(sp.name));

                        }

                    }

参考:https://www.gamasutra.com/blogs/LiorTal/20141208/231690/Finding_Missing_Object_References_in_Unity.php

完整代码:

using System.Linq;

using UnityEditor;

using UnityEngine;

using UnityEngine.SceneManagement;

public class FindMissingRefrence : MonoBehaviour

{

         [MenuItem("Tools/Find Missing Refrence In Current Scene")] 

         public static void FindMissingRefrencesInCurrentScene()

         {

                 var objects = GetSceneObjects();

                 FindMissingReferences(SceneManager.GetActiveScene().name, objects);

         }

         private static GameObject[] GetSceneObjects() => Resources.FindObjectsOfTypeAll().Where(go => string.IsNullOrEmpty(AssetDatabase.GetAssetPath(go)) && go.hideFlags == HideFlags.None).ToArray();

         private static void FindMissingReferences(string context, GameObject[] objects) 

         {

                 foreach(var go in objects)

                 {

                         var components = go.GetComponents();

                        foreach(var c in components)

                        {

                            if(!c)

                            {

                                    Debug.LogError("Missing Component in GO: " + FullPath(go), go);

                                    continue;

                                }

                            SerializedObject so = new SerializedObject(c);

                            var sp = so.GetIterator();

                            while(sp.NextVisible(true))

                            {

                                    if(sp.propertyType == SerializedPropertyType.ObjectReference)

                                    {

                                            if(sp.objectReferenceValue == null  && sp.objectReferenceInstanceIDValue != 0)

                                            {

                                                    ShowError(context, go, c.GetType().Name, ObjectNames.NicifyVariableName(sp.name));

                                              }

                                        }

                                }

                    }

                }

            }

            private static void ShowError(string context, GameObject go, string c, string property) => Debug.LogError($"Missing Refrence in : [{context}]{FullPath(go)}. Component: {c}, Property: {property}");

            private static string FullPath(GameObject go) => go.transform.parent == null ? go.name : FullPath(go.transform.parent.gameObject) + "/" + go.name;

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,131评论 19 139
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些阅读 2,062评论 0 2
  • pyspark.sql模块 模块上下文 Spark SQL和DataFrames的重要类: pyspark.sql...
    mpro阅读 9,545评论 0 13
  • 记:2015.12 “爱无底线”,就发生在身边人与小动物之间的真实故事! 1 谁都知道Z先生是一个特别有整洁癖的人...
    风和日丽wy阅读 775评论 4 5