Unity: "The referenced script (Unknown) on this Behaviour is missing!"
Asked Answered
K

14

24

Sometimes when I start my game, I get pointless warnings. I do not know where they come from and I do not have any objects that address a script that does not exist. How can I remove or fix these messages?

Console:

Inspector:

When I right click on the icon of the file in the inspector I get two possible options. Both of them do not work or when I try to click on them nothing happens.

Inspector context menu:

Karlenekarlens answered 3/3, 2019 at 14:40 Comment(3)
Did you find an answer to this question?Triboelectricity
Sorry, I didn't have this problem any more after newer unity versions. So I don't know if any of the given answers would have worked.Karlenekarlens
Ok. I have the same problem and I will try to update unity.Triboelectricity
G
16

It happens when the file and the name class has not the same name.

Example:

  • The file is named SingleCube.cs
  • The class definition is public class Cube : MonoBehaviour

In this case, Unity is not able to link the file and the class. Both have to have the same name.

  • The file should be SingleCube.cs
  • And the class definition public class SingleCube : MonoBehaviour
Gustavo answered 29/2, 2020 at 11:8 Comment(2)
Also when the case does not match: SingleCube.cs and class SinglecubeSymbolism
Is there an easy way to find files with this issue?Lauber
S
14

The Editor script on the below page from Gigadrill Games did the job for me. Many thanks to them for creating this - missing scripts is a regular problem I have with my Unity workflow.

Just create an Editor folder anywhere in your project hierarchy (e.g. Plugins/Find Missing Scripts/Editor) and extract the script file in the RAR file linked in the below article.

You'll have an option on your 'Window' menu in Unity to track down those pesky missing script components.

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

Code also reproduced below:

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);
            }
        }
    }
}
Susy answered 13/8, 2021 at 13:48 Comment(0)
E
6

In my case the problem was a reference to a Component that had been deleted, inside a prefab file which was overridden by a variant which did not include the Component. So when I instantiated the variant, the missing component was briefly referenced as it was removed, causing this generic warning with no useful identifying data. I found it by:

  • restoring all recently deleted components one at a time until the error stopped

  • copying the guid from that component's .meta file.

  • doing a raw text search for the guid in all *.prefab files (also *.scene and *.asset)

This requires Project Settings > Editor > Asset Serialization > Mode = Force Text.

Expiratory answered 28/5, 2021 at 17:42 Comment(1)
The prefab thing was my problemTrash
M
5

I had this same issue as well. I think it's caused by deleting the default scene but not changing the "Scenes in Build" in the build settings. Here's how I fixed it.

  1. Go to your build settings (File > Build Settings). There should a greyed out box that says "deleted". This is the (now missing) default scene.
  2. Right click on it and remove it
  3. Add your current scene
Menace answered 13/7, 2020 at 10:16 Comment(0)
L
2

That happens when you've changed the C# class name of a script, or you changed the script's file name in the project, so that they don't match. In your case, the problem is with whichever script you have highlighted in your Inspector screenshot.

Leban answered 3/3, 2019 at 14:47 Comment(7)
No, in my case, each class name matches the name of the file it belongs to.Karlenekarlens
What file do you have highlighted when you took your screenshot of the Inspector?Leban
I have clicked on the warning.Karlenekarlens
I mean in Unity's Project view. What file was selected when you took that screenshot of the Inspector?Leban
I have never been to the Project view. Like I said, I was just clicking on the warning from the console, and then it showed up in the inspector.Karlenekarlens
You'll need to open up your Project view to see which file is causing that problem. Open the Project view, then double click on your error, then see which script file gets highlighted in the Project view.Leban
When I click on the warning nothing happens in the project viewKarlenekarlens
Z
2

In my case this was not due to a missing script in the scene, but inside a Prefab that the scene uses.

Thanks to a post in Unity Forums.

Zelig answered 30/11, 2022 at 21:7 Comment(1)
I logged in just to thank you!Drabble
W
1

You can remove this un-reachable script from inspector panel and load again as a component. So you can use your script with no problem agin.

Whitson answered 3/3, 2019 at 15:2 Comment(1)
There is no option to remove the script from the inspector.Karlenekarlens
P
1

If, or when, you first start your project -- you move and/or rename the original default scene that was included in the "scenes" folder, Unity will throw an ever-increasing number of these false references until you end up sitting in the park throwing breadcrumbs at yourself. They can get into the thousands.

Here's how to fix it:

  1. Go into "File -> Build Settings" and delete all the "Scenes in Build" then exit out of that window.
  2. Find that original renamed scene, double click it so it is active, and go to "File -> Save As..."
  3. Save this scene as a brand new scene with a new name. This is crucial. Don't simply overwrite the file that is there. For instance, if the current file is named "scene_battlefield", rename it to something like "scene_battlefield_whatever".
  4. Delete the new file ("scene_battlefield_whatever") by right-clicking on it in the "Assets" panel. However, you'll notice that the name at the top of the screen still says "scene_battlefield_whatever".
  5. Go back to "File -> Save As..." again and this time click on the original file you had prior to renaming and overwrite it. The name at the top of the screen will change as expected (to "scene_battlefield").
  6. Go back to "File -> Build Settings", add "scene_battlefield" (or whatever it's called), and build the program to a folder. After the build is complete, you can delete the build. This built version of your program is unimportant.
  7. Restart Unity and load up the project as usual.

Basically the "Save As..." rewrites over all the old legacy script connections.

If you can't remember which scene in your game is the original renamed scene, you'll need to redo the "Save As..." part for each scene. However, you only have to do the "Build Settings" once.

And that's it. You should never have these random scripts popping up again. Hope that helps.

Phenyl answered 4/10, 2019 at 2:8 Comment(0)
E
0

This usually shows up when you assign a script to an object and then delete the script from your project. If you're sure that no object in your scene has this script assigned, perhaps some object that gets instantiated at the run time does? Also, check out this page, it might help you find the source of these errors.

Edie answered 3/3, 2019 at 14:48 Comment(1)
I tried the script on your linked page, but unfortunately it didn't find anything.Karlenekarlens
O
0

File name and public class name should be same like Test.cs so public class should be public class Test

enter image description here

Occur answered 11/3, 2021 at 15:39 Comment(0)
H
0

In my case I had used Window->Rendering->Lighting->"Generate Lighting" on a Scene...."Scene1" for example. Unity3d then created a Scene1 folder inside my Scenes directory parallel to my Scene1 asset.

I later renamed Scene1 to Level1, but the directory Scene1 did not change accordingly. I got these errors until I renamed the lighting folder to Level1 as well.

Hialeah answered 29/6, 2021 at 14:4 Comment(0)
F
0

First click "Add Component" in the Editor. Add the script named "NameFinder". Open your IDE (Rider, Visual Studio etc.). Fill the class with following lines.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NameFinder : MonoBehaviour
{
    // Update is called once per frame
    void Update()
    {
        Debug.Log("Name of the object is:" + gameObject.name);
    }
}

Come back to Unity and watch console while in Play mode. Name of your object should be printed each frame. If you can find it in the scene, good. Get out of the play mode and delete it.

If you can not find it in your scene, your scene file is corrupted. Close unity, open your scene file in a text editor, search for the name of your object and delete the object manually.

You may want to see how Unity stores scene objects. In my case I had to search for GUID and delete the stuff that has the same reference. (Transform and other components should be removed.)

Frederico answered 22/10, 2022 at 18:6 Comment(0)
S
0

Actually, for me it is when I forget to end the game and then start editing the script!

When I save my script and go back into Unity I get this error.

Of course if I remember to end my game before editing this error doesn't pop up.

Seleta answered 28/11, 2022 at 17:37 Comment(0)
M
0

If you use Prefab with a script attach to it and you attach different script, then delete the script from the inspector as well as from Prefab inspector.

Mongolic answered 3/7 at 9:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.