Game Dev Cheat Sheet

Editor errors

Can't add script component 'X' because the script class cannot be found. Make sure that there are no compile errors and that the file name and class name match.

The exact message

Can't add script component 'X' because the script class cannot be found. Make sure that there are no compile errors and that the file name and class name match.
Variants of this message
  • Can't add script component because the script class cannot be found
  • because the script class cannot be found
  • Make sure that there are no compile errors and that the file name and class name match

What it means

Unity cannot find a usable MonoBehaviour class inside the file you are trying to add. The message gives you the two most common reasons, and they are worth taking literally: either the project does not currently compile, so no classes exist to bind to, or the file name does not match the class name inside it. Unity requires that match in order to locate a MonoBehaviour in a file at all.

Causes and fixes

Ranked by how often they actually occur, most common first.

  1. The project has compile errors

    While any script in the project fails to compile, Unity has no usable assembly, so no class can be added as a component. The error you see mentions the script you were adding, but the actual fault is often in a completely unrelated file. This is the first thing to check, and it is why the message names it first.

    The fix: Open the Console, clear the filters so errors are visible, and fix the first error listed. Adding components works again as soon as compilation succeeds.

    Source: Unity Discussions: can't add script component, script class cannot be found

  2. The file name and the class name do not match

    Unity locates a MonoBehaviour by matching the class name to the file name, so PlayerController.cs must contain a class called PlayerController. The match is case sensitive and does not tolerate trailing spaces, a duplicated suffix such as PlayerController 1.cs from a copy-paste, or a file created with one name and a class typed with another.

    The fix: Rename the file or the class so the two are identical. Rename the file from the Project window so its .meta stays with it, and remember that a copied file arrives as Script 1.cs, which will never match.

    PlayerController.cs must declare exactly this class name.

    using UnityEngine;
    
    // File: Assets/Scripts/PlayerController.cs
    // The class name below must match the file name exactly, including case.
    public class PlayerController : MonoBehaviour
    {
        void Update() { }
    }
    
    // A second MonoBehaviour in the same file cannot be added as a component,
    // because its name does not match the file name.
    public class HelperBehaviour : MonoBehaviour { }

    Source: Unity Discussions: file name must match the class name for a MonoBehaviour

  3. The class does not derive from MonoBehaviour

    Only classes inheriting from MonoBehaviour can be attached to a GameObject. A plain class, a ScriptableObject, a static class or a struct cannot, and Unity reports that as the class not being findable rather than as a type mismatch. Forgetting the base class entirely when creating a script by hand rather than through the Create menu is the common route in.

    The fix: Add the MonoBehaviour base class if the script is meant to be a component. A ScriptableObject belongs in the Project window and is created through the Assets menu rather than added to a GameObject.

    Source: Unity Manual: MonoBehaviour

  4. The class is abstract, generic, or nested in another class

    Unity cannot instantiate an abstract class, an open generic class, or a class nested inside another type, so none of them can be added as components even when they derive from MonoBehaviour and the file name matches. This catches people building a base-class hierarchy, because the base is exactly the thing you cannot attach.

    The fix: Attach a concrete subclass rather than the abstract base. For a generic MonoBehaviour, declare a concrete non-generic subclass that closes the type parameter, and attach that.

    The generic base cannot be attached; the closed subclass can.

    using UnityEngine;
    
    // Cannot be added to a GameObject: abstract.
    public abstract class Weapon : MonoBehaviour
    {
        public abstract void Fire();
    }
    
    // Cannot be added to a GameObject: open generic.
    public abstract class Pool<T> : MonoBehaviour where T : Component { }
    
    // Both of these can, because they are concrete and closed.
    public class Shotgun : Weapon
    {
        public override void Fire() { }
    }
    
    public class ProjectilePool : Pool<Rigidbody> { }

    Source: Unity Manual: MonoBehaviour

  5. The script is in an assembly the object cannot use

    A script inside a folder named Editor compiles into an Editor-only assembly and cannot be attached to a GameObject in a scene. The same applies to a script inside an assembly definition whose platform or define constraints exclude it from the current context. The file is present and compiles, so nothing looks wrong.

    The fix: Move the script out of the Editor folder if it is meant to run in the game. If it lives under an asmdef, check that assembly's platform and define constraints in the Inspector.

    Source: Unity Manual: Special folder names

How to prevent it

Create scripts through Assets > Create > MonoBehaviour Script rather than making files by hand. The template arrives with the class name already matching the file name and the correct base class.

Rename scripts from inside the Project window. Renaming in the file system leaves the .meta behind, and renaming the file without renaming the class breaks the match Unity relies on.

Keep one MonoBehaviour per file, named after the file. It is a Unity requirement in practice for anything you intend to attach, and it also matches this project's own one-component-per-file convention.

Clear the Console before diagnosing this error. The message is frequently a downstream symptom of a compile error in an unrelated script, and an uncleared Console makes that hard to see.

Unity version differences

Behaviour is unchanged across supported versions. The Create menu entry was renamed from C# Script to MonoBehaviour Script in Unity 6, but the template it produces is equivalent.

Sources

Frequently asked questions

The file name matches, so why does it still fail?
Check for a mismatch you cannot see: a trailing space in the file name, different casing, or a copy suffix such as Script 1.cs. After that, check the class itself. It must derive from MonoBehaviour and must not be abstract, generic or nested inside another class. Finally, check whether the project compiles at all, because nothing can be added while it does not.
Can I put two MonoBehaviours in one file?
C# allows it and the code compiles, but only the class whose name matches the file name can be added as a component through the Inspector. The other is usable from code but cannot be attached by dragging. Keeping one MonoBehaviour per file avoids the confusion entirely.
Why can I not add my abstract base class?
Unity has to instantiate a component when it is added, and an abstract class cannot be instantiated. The same applies to an open generic class. Attach a concrete subclass instead; for a generic base, declare a non-generic subclass that fills in the type parameter and attach that.
Does the namespace matter?
No. A MonoBehaviour in a namespace is added the same way, and the file name still needs to match the class name rather than the fully qualified name. Namespaces matter for referencing the type from other scripts, which is a CS0246 problem rather than this one.
Why does this happen right after I import an asset package?
Usually because the package brought compile errors with it, often from targeting a different Unity version or from duplicate copies of a shared library. Until those are resolved nothing can be added as a component. Read the Console rather than the add-component message, because the real fault will be there.

Last updated: