반응형
Notice
Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

Do Something IT

Finding Missing References in Unity(Mssing난 컴포넌트 찾기) 본문

Unity3D

Finding Missing References in Unity(Mssing난 컴포넌트 찾기)

아낙시만더 2015. 5. 19. 11:55
반응형

참조 바로가기 

This post shows a short and simple solution for finding missing references in Unity.

EDIT: The original code was improved upon feedback (thanks: Amir Barak, Thomas Viktil, Alex Kogan, Amir Ebrahimi).

The code was updated to include:

  • Error context (can click to get to the game object)
  • Find missing components (not only missing references inside scripts)
  • Find inactive scene objects as well
  • Formatting – keep it all under 80 chars

Missing References

A missing reference is different from having no reference at all (in which case the inspector shows “None”). These can occur for a variety of reasons, for example: moving asset files outside of the Unity editor, a result of a mixup in .meta files that results in having a link to an invalid object id (or due to a bug – see this bug).

The major issue is that missing references can be hidden somewhere in the project, only to be found too late in the process. Luckily, we can exercise some editor scripting to the rescue…

Solution

Here is the full code for finding these missing references, in case you run into this issue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System.Collections;
using System.Linq;
using UnityEditor;
using UnityEngine;
 
public class MissingReferencesFinder : MonoBehaviour
{
    [MenuItem("Tools/Show Missing Object References in scene", false, 50)]
    public static void FindMissingReferencesInCurrentScene()
    {
        var objects = GetSceneObjects();
        FindMissingReferences(EditorApplication.currentScene, objects);
    }
 
    [MenuItem("Tools/Show Missing Object References in all scenes", false, 51)]
    public static void MissingSpritesInAllScenes()
    {
        foreach (var scene in EditorBuildSettings.scenes)
        {
            EditorApplication.OpenScene(scene.path);
            FindMissingReferences(scene.path, Resources.FindObjectsOfTypeAll<GameObject>());
        }
    }
 
    [MenuItem("Tools/Show Missing Object References in assets", false, 52)]
    public static void MissingSpritesInAssets()
    {
        var allAssets = AssetDatabase.GetAllAssetPaths();
        var objs = allAssets.Select(a => AssetDatabase.LoadAssetAtPath(a, typeof(GameObject)) as GameObject).Where(a => a != null).ToArray();
 
        FindMissingReferences("Project", objs);
    }
 
    private static void FindMissingReferences(string context, GameObject[] objects)
    {
        foreach (var go in objects)
        {
            var components = go.GetComponents<Component>();
 
            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 GameObject[] GetSceneObjects()
    {
        return Resources.FindObjectsOfTypeAll<GameObject>()
            .Where(go => string.IsNullOrEmpty(AssetDatabase.GetAssetPath(go))
                   && go.hideFlags == HideFlags.None).ToArray();
    }
 
    private const string err = "Missing Ref in: [{3}]{0}. Component: {1}, Property: {2}";
 
    private static void ShowError (string context, GameObject go, string c, string property)
    {
        Debug.LogError(string.Format(err, FullPath(go), c, property, context), go);
    }
 
    private static string FullPath(GameObject go)
    {
        return go.transform.parent == null
            ? go.name
                : FullPath(go.transform.parent.gameObject) + "/" + go.name;
    }
}

Paste this code into an editor folder, load the scene you’d like to find missing references in, and click the menu option “Tools/Find Missing references in scene”.

Any issues found will be shown in the Console (as errors).

The code is also available on GitHub

반응형

'Unity3D' 카테고리의 다른 글

[Unity3D]Asset의 Import, Reimport, Delete, Move 정보 찾기  (0) 2015.06.10
[Unity] DepthMask  (0) 2015.05.20
Unity Patch 정보  (0) 2015.05.11
Simple Observer Pattern  (0) 2015.05.11
포물선정보  (0) 2015.04.28
Comments