Unity:“此行为的引用脚本(未知)丢失!”

Tim*_*ean 13 unity-game-engine

有时,当我开始游戏时,会收到毫无意义的警告。我不知道它们来自哪里,而且我没有任何对象可以解决不存在的脚本。如何删除或修复这些消息?

安慰:

检查员:

当我在检查器中右键单击文件图标时,我会得到两个可能的选项。它们都不起作用,或者当我尝试点击它们时没有任何反应。

检查器上下文菜单:

Chr*_*sth 14

下页 Gigadrill Games 的编辑器脚本为我完成了这项工作。非常感谢他们创建了这个 - 缺少脚本是我的 Unity 工作流程中经常遇到的问题。

只需在项目层次结构中的任何位置创建一个编辑器文件夹(例如插件/查找丢失的脚本/编辑器),然后将脚本文件提取到下面文章中链接的 RAR 文件中。

您将在 Unity 的“窗口”菜单上找到一个选项来追踪那些令人讨厌的缺失脚本组件。

https://gigadrillgames.com/2020/03/19/finding-missing-scripts-in-unity/

代码也转载如下:

using UnityEditor;
using UnityEngine;

namespace AndroidUltimatePlugin.Helpers.Editor
{
    public class FindMissingScriptsRecursively : EditorWindow
    {
        static int _goCount = 0, _componentsCount = 0, _missingCount = 0;

        [MenuItem("Window/FindMissingScriptsRecursively")]
        public static void ShowWindow()
        {
            GetWindow(typeof(FindMissingScriptsRecursively));
        }

        public void OnGUI()
        {
            if (GUILayout.Button("Find Missing Scripts in selected GameObjects"))
            {
                FindInSelected();
            }

            if (GUILayout.Button("Find Missing Scripts"))
            {
                FindAll();
            }
            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("Component Scanned:");
                EditorGUILayout.LabelField("" + (_componentsCount == -1 ? "---" : _componentsCount.ToString()));
            }
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("Object Scanned:");
                EditorGUILayout.LabelField("" + (_goCount == -1 ? "---" : _goCount.ToString()));
            }
            EditorGUILayout.EndHorizontal();
            
            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.LabelField("Possible Missing Scripts:");
                EditorGUILayout.LabelField("" + (_missingCount == -1 ? "---" : _missingCount.ToString()));
            }
            EditorGUILayout.EndHorizontal();
        }

        private static void FindAll()
        {
            _componentsCount = 0;
            _goCount = 0;
            _missingCount = 0;
            
            string[] assetsPaths = AssetDatabase.GetAllAssetPaths();

            foreach (string assetPath in assetsPaths)
            {
                Object[] data = LoadAllAssetsAtPath(assetPath);
                foreach (Object o in data)
                {
                    if (o != null)
                    {
                        if (o is GameObject)
                        {
                            FindInGO((GameObject) o);
                        }
                    }
                }
            }
            
            Debug.Log($"Searched {_goCount} GameObjects, {_componentsCount} components, found {_missingCount} missing");
        }

        public static Object[] LoadAllAssetsAtPath(string assetPath)
        {
            return typeof(SceneAsset).Equals(AssetDatabase.GetMainAssetTypeAtPath(assetPath))
                ?
                // prevent error "Do not use readobjectthreaded on scene objects!"
                new[] {AssetDatabase.LoadMainAssetAtPath(assetPath)}
                : AssetDatabase.LoadAllAssetsAtPath(assetPath);
        }

        private static void FindInSelected()
        {
            GameObject[] go = Selection.gameObjects;
            _goCount = 0;
            _componentsCount = 0;
            _missingCount = 0;
            foreach (GameObject g in go)
            {

                FindInGO(g);
            }

            Debug.Log($"Searched {_goCount} GameObjects, {_componentsCount} components, found {_missingCount} missing");
        }

        private static void FindInGO(GameObject g)
        {
            _goCount++;
            Component[] components = g.GetComponents<Component>();
            for (int i = 0; i < components.Length; i++)
            {
                _componentsCount++;
                if (components[i] == null)
                {
                    _missingCount++;
                    string s = g.name;
                    Transform t = g.transform;
                    while (t.parent != null)
                    {
                        var parent = t.parent;
                        s = parent.name + "/" + s;
                        t = parent;
                    }

                    Debug.Log(s + " has an empty script attached in position: " + i, g);
                }
            }

            // Now recurse through each child GO (if there are any):
            foreach (Transform childT in g.transform)
            {
                //Debug.Log("Searching " + childT.name  + " " );
                FindInGO(childT.gameObject);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Sar*_*way 6

就我而言,问题是对预制文件中已删除的组件的引用,该文件被不包含该组件的变体覆盖。因此,当我实例化该变体时,缺失的组件在被删除时被短暂引用,导致此通用警告没有有用的识别数据。我通过以下方式找到了它:

  • 一次恢复所有最近删除的组件,直到错误停止

  • 从该组件的 .meta 文件复制 guid。

  • 在所有 *.prefab 文件(还有 *.scene 和 *.asset)中对 guid 进行原始文本搜索

这需要项目设置 > 编辑器 > 资产序列化 > 模式 = 强制文本。


Ser*_*ema 5

当文件和名称类的名称不同时,就会发生这种情况。

例子:

  • 该文件名为 SingleCube.cs
  • 类定义是 public class Cube : MonoBehaviour

在这种情况下,Unity 无法链接文件和类。两者必须具有相同的名称。

  • 该文件应该是 SingleCube.cs
  • 和类定义 public class SingleCube : MonoBehaviour

  • 有没有一种简单的方法可以找到存在此问题的文件? (2认同)

小智 5

我也有同样的问题。我认为这是由于删除了默认场景但没有更改构建设置中的“构建中的场景”引起的。这是我修复它的方法。

  1. 转到您的构建设置(文件 > 构建设置)。应该有一个灰色的框,上面写着“已删除”。这是(现已丢失)默认场景。
  2. 右键单击它并将其删除
  3. 添加您当前的场景


Ben*_*bin 2

当您更改了脚本的 C# 类名,或者更改了项目中脚本的文件名,导致它们不匹配时,就会发生这种情况。就您而言,问题出在您在检查器屏幕截图中突出显示的任何脚本。