Game Dev Cheat Sheet

Compiler errors

error CS0246: The type or namespace name 'X' could not be found (are you missing a using directive or an assembly reference?)

The exact message

error CS0246: The type or namespace name 'X' could not be found (are you missing a using directive or an assembly reference?)
Variants of this message
  • The type or namespace name 'X' could not be found (are you missing a using directive or an assembly reference?)
  • The type or namespace name could not be found
  • CS0246
  • error CS0246: The type or namespace name 'PlayerController' could not be found (are you missing a using directive or an assembly reference?)

What it means

The compiler reached a type name it cannot resolve from where you used it. That is broader than a spelling mistake: the type may exist but sit in a namespace you have not imported, in an assembly your code does not reference, or in an assembly that is not compiled for the platform you are building. The name in quotes is what the compiler could not find, and the parenthetical is a hint rather than a diagnosis.

Causes and fixes

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

  1. The type name is misspelt or has the wrong casing

    C# is case sensitive, so Rigidbody2d does not resolve to Rigidbody2D. This is the most common cause by a wide margin, and it is worth eliminating first because it takes seconds. Types that differ only in case or in a trailing digit, such as Collider and Collider2D, account for a large share of these.

    The fix: Check the spelling and casing against the Scripting API. Deleting the name and letting your editor's autocomplete reinsert it is faster than reading it character by character, and it also confirms the type is visible from that file.

    Source: Unity Support: What is CS0246?

  2. The namespace is not imported

    The type exists but lives in a namespace the file has not imported, which is what the parenthetical hint is about. Unity's own APIs are split across several: UI components need UnityEngine.UI, TextMeshPro needs TMPro, lists and dictionaries need System.Collections.Generic, and the new Input System needs UnityEngine.InputSystem.

    The fix: Add the using directive at the top of the file. Where you do not know which namespace a type belongs to, the Scripting API page for that type names it in the heading.

    The imports Unity scripts most often turn out to be missing.

    using System.Collections;               // IEnumerator, for coroutines
    using System.Collections.Generic;       // List<T>, Dictionary<TKey, TValue>
    using UnityEngine;
    using UnityEngine.UI;                   // Button, Image, Slider
    using UnityEngine.SceneManagement;      // SceneManager
    using TMPro;                            // TextMeshProUGUI
    using UnityEngine.InputSystem;          // InputAction, PlayerInput
    
    public class HudController : MonoBehaviour
    {
        [SerializeField] private Button startButton;
        [SerializeField] private TextMeshProUGUI scoreLabel;
        private readonly List<string> log = new();
    }

    Source: Unity Support: What is CS0246?

  3. Another compile error is hiding this one

    When a script fails to compile, the types it declares do not exist as far as every other script is concerned. A single syntax error in one file therefore produces CS0246 in every file that uses its types, which is why this error often arrives in bulk. The reported errors are symptoms; only one of them is the cause.

    The fix: Sort the Console by the order errors were reported and fix the first one, then let Unity recompile before reading the rest. Fixing CS0246 errors one by one from the top of a list of fifty is wasted effort when a missing brace in one file produced all of them.

    Source: Unity Support: How do I interpret a compiler error?, Unity Discussions: over 100 CS0246 errors appearing for no apparent reason

  4. An assembly definition does not reference the other assembly

    An .asmdef file compiles the folder it sits in into a separate assembly, and that assembly can only see types from assemblies it explicitly references. Adding an asmdef to a folder therefore breaks every reference into it from code that has not been told about it. This is the cause most likely to be missed, because the code is correct and unchanged; only the project structure moved.

    The fix: Select the asmdef that reports the error and add the other assembly under Assembly Definition References in the Inspector. Where a package supplies the type, its assembly name is listed on the package's page in the Package Manager.

    Source: Unity Manual: Assembly definitions

  5. Editor-only code is being used at runtime

    Scripts in a folder named Editor compile into an Editor-only assembly that does not exist in a build, as do types in the UnityEditor namespace. Code that references them compiles fine in the Editor and then fails at build time with CS0246, which is why this one typically appears the first time you build rather than while developing.

    The fix: Wrap Editor-only usage in #if UNITY_EDITOR so it is compiled out of players, or move the shared type into a runtime assembly. Note that an Editor folder nested inside a folder that has its own asmdef does not get the usual Editor-assembly treatment, which produces the same error for a different reason.

    The directive must wrap both the using and every use of the type.

    using UnityEngine;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    
    public class LevelMarker : MonoBehaviour
    {
        public void Ping()
        {
    #if UNITY_EDITOR
            // Compiled out of the player, where UnityEditor does not exist.
            EditorGUIUtility.PingObject(gameObject);
    #endif
        }
    }

    Source: Unity Discussions: build fails with CS0246 on the Editor namespace, Unity Issue Tracker: build fails with an Editor folder inside a folder that has an Assembly Definition

  6. A package or plugin is missing, or excluded on this platform

    Types from a package that is not installed, or from a .dll excluded for the current build target in its plugin import settings, do not resolve. Opening a project on another machine without its packages restored, or building for a platform a plugin does not support, produces this. Version control that ignores Packages/manifest.json changes has the same effect.

    The fix: Confirm the package is present in the Package Manager, and for a .dll check its Inspector to see which platforms it is included for. Where the type comes from an asset store package, reimporting it is usually quicker than diagnosing which file is absent.

    Source: Unity Manual: Import and configure plug-ins

How to prevent it

Fix the first compile error in the Console and recompile before reading the others. Most large batches of CS0246 come from one broken file, and working from the top means the list shrinks on its own.

Add assembly definitions deliberately rather than incrementally. Each one is a compilation boundary, and adding one to an existing folder breaks every reference into it until those references are declared.

Build for your target platform regularly rather than only at release. Editor-only code compiles happily until the first build, so a weekly build catches this class of error while the change that caused it is still fresh.

Keep Packages/manifest.json in version control and review changes to it. A teammate adding a package that you do not have produces CS0246 on code that is otherwise correct.

Unity version differences

CS0246 is a standard C# compiler error and its text comes from Roslyn rather than Unity, so it is identical across Unity versions. What changes between versions is which assemblies exist: Unity 2019 moved several APIs into packages, so code written for an older version can produce CS0246 purely because the package is not installed.

Sources

Frequently asked questions

Why did I suddenly get a hundred CS0246 errors?
Because one script failed to compile and every type it declared vanished from the compiler's view. Each script that used those types then reported its own CS0246. Fix the earliest unrelated error in the Console, let Unity recompile, and the rest usually disappear together.
What is the difference between CS0246 and CS0234?
CS0246 means the compiler could not find the type or namespace at all. CS0234 means it found the containing namespace but not the member you asked for inside it, as in UnityEngine.Foo where UnityEngine exists but Foo does not. CS0234 is therefore the narrower signal: the assembly is referenced, but the type is not in it.
My code is correct and it still fails, so what else should I check?
Assembly definitions are the usual answer. An .asmdef makes its folder a separate assembly that can only see what it explicitly references, so correct code stops compiling the moment one is added nearby. Check the asmdef reporting the error for a missing entry under Assembly Definition References, and check whether an Editor folder has ended up inside an asmdef folder.
Why does it only fail when I build, not in the Editor?
Because the Editor compiles assemblies the player does not have. Anything in a folder named Editor, and anything in the UnityEditor namespace, exists only in the Editor. Code referencing it works while you develop and fails at build time. Wrapping the usage in #if UNITY_EDITOR resolves it.
Does restarting Unity or deleting the Library folder help?
Occasionally, but it is not the first thing to try and it is rarely the real fix. Deleting Library forces a full reimport that can clear a stale compilation state, at the cost of a long reimport. Work through the causes above first; if the code is genuinely correct and the assembly references are right, only then is a stale cache a plausible explanation.

Last updated: