Object
TypeClass
NamespaceUnityEngine
Inherits(none)
Inherited byGameObject, Component, ScriptableObject, Material, Texture, and every other Unity asset type

Object

UnityEngine.Object is the base class of everything Unity manages: GameObjects, components, materials, prefabs and so on. It is where the most important "create and destroy" functions live: Instantiate and Destroy.

Not the same as C#'s objectUnityEngine.Object and C#'s System.Object (lowercase object) are different. If you have using System; and using UnityEngine; together and write Object, the compiler may complain that it's ambiguous. Write UnityEngine.Object to be explicit.

Properties

NameTypeDescription
namestringThe object's name. For a GameObject, this is what the Hierarchy shows.
hideFlagsHideFlagsAdvanced: hide the object from the Hierarchy or stop it being saved.

Static Methods

MethodReturnsDescription
Instantiate(original)Same type as originalMakes a copy. For a GameObject or prefab, copies all components and children.
Instantiate(original, position, rotation)Same typeCopy placed at a world position and rotation.
Instantiate(original, parent)Same typeCopy created as a child of parent.
Instantiate(original, position, rotation, parent)Same typeAll of the above.
Destroy(obj)voidRemoves a GameObject, component or asset at the end of the current frame.
Destroy(obj, t)voidRemoves it after t seconds.
DontDestroyOnLoad(obj)voidKeeps a root GameObject alive when a new scene loads (music players, game managers).
FindFirstObjectByType<T>()TFinds the first active object of type T in loaded scenes. Slow; don't call every frame.
FindAnyObjectByType<T>()TLike above but faster, when you don't care which one you get.
FindObjectsByType<T>(FindObjectsSortMode.None)T[]All active objects of type T. Slow.
Unity 6 name changeFindObjectOfType<T>() and FindObjectsOfType<T>() from older tutorials are deprecated. Use FindFirstObjectByType, FindAnyObjectByType or FindObjectsByType.

Code Samples

Spawning and cleaning up

using UnityEngine;

public class Explosion : MonoBehaviour
{
    [SerializeField] private GameObject explosionPrefab;

    public void Explode()
    {
        // Create the effect where this object is.
        GameObject fx = Instantiate(explosionPrefab, transform.position, Quaternion.identity);

        // Remove the effect after 2 seconds.
        Destroy(fx, 2f);

        // Remove this object right away (at the end of this frame).
        Destroy(gameObject);
    }
}

A music player that survives scene changes

using UnityEngine;

public class MusicPlayer : MonoBehaviour
{
    private static MusicPlayer instance;

    void Awake()
    {
        // If one already exists (we came back to the menu), remove the duplicate.
        if (instance != null)
        {
            Destroy(gameObject);
            return;
        }
        instance = this;
        DontDestroyOnLoad(gameObject); // must be a root object (no parent)
    }
}

What happens at runtime

Destroy(obj)

  1. The object is marked for destruction. It still exists for the rest of this frame: code after Destroy keeps running, and other scripts can still see it.
  2. After the current Update loop finishes (but before rendering), Unity calls OnDisable and OnDestroy on its scripts, then removes it and all its children.
  3. After that, any variable pointing to it compares equal to null (see below).

The "fake null"

A TV remote. Your variable is the remote; the engine object is the TV. Destroy throws the TV away, but you're still holding the remote. Unity's == checks whether the TV is still there. C#'s ?. only checks whether you're holding a remote, so it says "yes" and you press buttons on a TV that isn't there.

Unity objects are two parts: a C# object you hold, and a native engine object behind it. Destroy deletes the native part. Unity overrides == so that a destroyed object is equal to null, even though the C# variable isn't technically empty.

Destroy(enemy);
// ...next frame:
if (enemy == null) { }   // true: Unity's == knows it was destroyed
if (enemy) { }           // false: same check, shorter
enemy?.TakeDamage(1);    // DANGER: ?. skips Unity's check, throws MissingReferenceException
Avoid ?. and ?? on Unity objectsThe C# operators ?., ?? and is null don't use Unity's overridden check, so they treat destroyed objects as still alive. Use if (x != null) instead.

Common Mistakes

See also