Last active
May 28, 2024 11:32
-
-
Save ProGM/a40acd8ebbb91eb7b2295e65d5eb42c8 to your computer and use it in GitHub Desktop.
Finding Missing References in Unity 5.4+
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Based on http://www.tallior.com/find-missing-references-unity/ | |
// It fixes deprecations and checks for missing references every time a new scene is loaded | |
// Moreover, it inspects missing references in animators and animation frames | |
using UnityEngine; | |
using UnityEditor; | |
using UnityEditor.SceneManagement; | |
using System.Linq; | |
[InitializeOnLoad] | |
public static class LatestScenes | |
{ | |
static string currentScene; | |
static LatestScenes() | |
{ | |
EditorApplication.hierarchyWindowChanged += hierarchyWindowChanged; | |
} | |
static void hierarchyWindowChanged() | |
{ | |
if (currentScene != EditorSceneManager.GetActiveScene().name) | |
{ | |
CheckMissingReferences.FindMissingReferencesInCurrentScene (); | |
currentScene = EditorSceneManager.GetActiveScene().name; | |
} | |
} | |
} | |
public static class CheckMissingReferences { | |
[MenuItem("Tools/Show Missing Object References in all scenes", false, 51)] | |
public static void MissingSpritesInAllScenes() | |
{ | |
foreach (var scene in EditorBuildSettings.scenes.Where(s => s.enabled)) | |
{ | |
EditorSceneManager.OpenScene(scene.path); | |
var objects = Object.FindObjectsOfType<GameObject> (); | |
FindMissingReferences(scene.path, objects); | |
} | |
} | |
[MenuItem("Tools/Show Missing Object References in scene", false, 50)] | |
public static void FindMissingReferencesInCurrentScene() | |
{ | |
var objects = Object.FindObjectsOfType<GameObject> (); | |
FindMissingReferences(EditorSceneManager.GetActiveScene().name, objects); | |
} | |
[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); | |
} | |
public static void FindMissingReferences(string sceneName, GameObject[] objects) | |
{ | |
foreach (var go in objects) | |
{ | |
var components = go.GetComponents<Component> (); | |
foreach (var c in components) | |
{ | |
var 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(FullObjectPath(go), sp.name, sceneName); | |
} | |
} | |
} | |
var animator = c as Animator; | |
if (animator != null) { | |
CheckAnimatorReferences (animator); | |
} | |
} | |
} | |
} | |
public static void CheckAnimatorReferences(Animator component) | |
{ | |
if (component.runtimeAnimatorController == null) { | |
return; | |
} | |
foreach (AnimationClip ac in component.runtimeAnimatorController.animationClips) { | |
var so = new SerializedObject (ac); | |
var sp = so.GetIterator (); | |
while (sp.NextVisible (true)) { | |
if (sp.propertyType == SerializedPropertyType.ObjectReference) { | |
if (sp.objectReferenceValue == null && sp.objectReferenceInstanceIDValue != 0) { | |
Debug.LogError ("Missing reference found in: " + FullObjectPath (component.gameObject) + "Animation: " + ac.name + ", Property : " + sp.name + ", Scene: " + EditorSceneManager.GetActiveScene ().name); | |
} | |
} | |
} | |
} | |
} | |
static void ShowError (string objectName, string propertyName, string sceneName) | |
{ | |
Debug.LogError("Missing reference found in: " + objectName + ", Property : " + propertyName + ", Scene: " + sceneName); | |
} | |
static string FullObjectPath(GameObject go) | |
{ | |
return go.transform.parent == null ? go.name : FullObjectPath(go.transform.parent.gameObject) + "/" + go.name; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm using your script in a couple of my projects. Today I stumbled over some functionality to slightly improve it. Debug.Log takes a second parameter
context
. This allows the Unity Editor to highlight thecontext
object in the scene tree when you click on the message. Works at least as long as it's in the current scene. Super useful.Required changes:
Line 98: add
ac
as second parameterLine 74: add
c
a fourth param and adjust ShowError as below.Hope that helps. Marco